Alternatives to Dependency Injection for Stateless Classes in C++

cdependency-injectiondesignunit testing

I am working on an application whereby I have designed classes to fit into several groups:

  • Immutable: initialised through constructors, uses copy-and-swap idiom (inc. move), can deep copy (i.e. clone), only has "getters" (not "setters") and implements comparison operators (==, !=);
  • Services: stateless classes that have methods that take immutables and/or services to perform desired functions;
  • Builders: factories etc to build immutables.

Unit testing on my immutables has been straightforward. I can use dependency injection through the constructors. This means I can swap in test classes to ensure I am unit testing (as opposed to integration testing). I can use the builders to construct my production objects. This element of my design I am happy with in terms of testing and production.

However, on my services I seem to only be able to keep these classes stateless and unit testable by using dependency injection via the method arguments.

For my services, an example function changes from:

virtual unsigned long foo() const override final;

…to:

virtual unsigned long foo(const ISomeInterface & dependency) const override final;

This means my service classes are testable, but then I have to now instantiate the dependencies outside of the class when using the code in production. For example:

// without dependency injection
Service service;
return service.foo();

// with dependency injection
Service service;
Dependency dependency;
return service.foo(dependency);

This has led to a large number of my service classes now needing at least 1 more argument for each class method. Note – this is the approach I am currently using in my code.

My question is this:

What alternatives do I have to this form of dependency injection that allow me to:

  • unit test stateless classes (without the dependencies)
  • keep these classes stateless
  • reduce / hide code that instantiates the dependencies (particularly if an object has multiple dependencies)

Note – I am also performing integration tests, which tests the real dependencies between objects.

Best Answer

If you donot like the additional constructor arguments for the dependencies you need a DI-Container to handle the instance creation for you.

You can use either an existing di-container framework or implement a poor mans version on your own

public PoorMansDiContainer : IPoorMansDiContainer {
    private IService mService = null;
    private IFooService mFooService = null;

    public IService getSingletonService() {
        if (mService == null) {
            mService = new ServiceImpl(getSingletonFooService());
        }
        return mService;
    }
    public IFooService getSingletonFooService() {
        if (mFooService == null) {
            mFooService = new FooServiceImpl();
        }
        return mFooService;
    }
}