Implementing factories for Dependency Injection

With Dependency Injection you typically inject an instance through constructor or property. That means that the whole dependency tree is resolved at once. In some cases, however, it is not acceptable and you need to control the creation of object instances from inside of a class. That’s when the need for object factories arises. Instead of injecting an instance of a class, a factory that produces instances of that type is injected. A common question is how to implement these factories. Factory pattern is the most obvious choice, but is it always the best?

Using delegates as factories

If all you need is to create instances of a type, .NET already comes with delegates that can be used as lightweight factories – Func<T>. When only a single instance can be created, Lazy<T> can be used – it might be useful when an instance is expensive to create. The following example illustrates using delegate factories:

public class DependentClass
{
    private Func<IDependency> dependencyFactory;

    public DependentClass(Func<IDependency> dependencyFactory)
    {
        this.dependencyFactory = dependencyFactory;
    }

    public void Execute()
    {
        var dependency = dependencyFactory();
        dependency.Execute();
    }
}

There are numerous advantages to this approach. First, you avoid introducing additional classes to your codebase, which helps you keep it simple. It also leads to simple tests, since you don’t need to create any seams for concrete factory classes or mocks for a factory interface. Supplying your own factory in tests becomes as simple as in the following example:

Func<IDependency> testDependencyFactory = () => new TestDependency();
var sut = new DependentClass(testDependencyFactory);

sut.Execute();

// do asserts

Furthermore, there’s also automatic support for Func<T> and Lazy<T> from IoC containers (I’ve only tested with Autofac, but others support it too). You register the dependency type and containers make sure that all your delegate factories work automatically without any explicit setup. Implementing a factory in your code then becomes a simple matter of wrapping dependency type with a delegate type.

What about cleanup?

Since using factories means that instances are not created in the composition root, we are responsible for cleaning up after ourselves. In many cases this means calling Dispose method of created instance. There’s no problem with that if you have a factory for concrete types which implement IDisposable interface. If you have a factory for an interface type, however, things become interesting. As a recommendation, interfaces should not inherit IDisposable and this means that there is no way to properly call Dispose method. One obvious example of this case are WCF client proxies.

If we are using delegate factory support from IoC containers, that is not a problem at all. Container tracks all instances created by it, even if it’s through delegate factory, and automatically calls Dispose method or executes any other code you specify for cleaning up.

If you’re not using an IoC container with automatic delegate factory support, cleaning up becomes your responsibility. Consider the following example of a unit test:

var dependency = new TestDependency();
Func<IDependency> testFactory = () => dependency;
var sut = new DependentClass(testFactory);

sut.Execute();

// do asserts

dependency.Dispose();

As you see, one must keep track of any dependencies that delegate factory creates and clean them up afterwards. That’s not really clean in my opinion. A traditional factory might be cleaner, if you define a method that does actual cleanup and require every dependent class to call this method. An example looks like this:

public interface IDependencyFactory
{
    // creates and instance of a class
    IDependency Create();
    
    // cleans up an instance that was create with Create method
    void Destroy(IDependency dependency);
}

The responsibility to call Destroy method now shifts to the dependent class, so cleaning up is done at the same scope as creating instances. This approach follows best practices better, but requires a new class (plus an interface, maybe) and makes the codebase larger, though. Unit tests do not require code to clean up with this approach, but will require a mock of the factory interface to supply fake objects.

Conclusion

Use Func<T> or Lazy<T> instead of Factory pattern when you need to create instances from within a DI-friendly class but no cleaning up is necessary. They are supported automatically by IoC containers, are easier to use in tests and do not require yet another class/abstraction to implement.

If instances that you create must be cleaned up manually after using them, choose what you like better – a traditional factory with a cleanup method or delegate factory. Both come with some trade-offs.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s