As we’re sloping down the glide path into the release of Unity 2.0 and Entlib 5, I wanted to start talking about some of the things that got added or changed in the container. For this post I want to discuss the new “automatic factories feature.”
This one was a recent addition that I threw in over the Christmas holiday, “inspired” by a feature recently added to AutoFac. At it’s core it answers a simple problem: what if I have to create objects through the container, but I don’t need them at injection time, but later?
This comes up in lots of situations. The object may be heavy, so you don’t want to create it until you absolutely need it. Or you need many of them, but can’t predict when.With Unity 1.2, you basically had two choices in this scenario.
First, you could inject the container as a dependency. This works, but has several issues. You’ve now coupled yourself to the container. Also, you have no way of knowing as a consumer of that class what needs to be in the container – the dependencies have become completely opaque.
A second choice is to inject a factory object. Then call the factory when you need to create an object; the factory implementation can call back into the container. This improves testability and solves the lack of metadata problem above. However, it has the downside of lots of boilerplate code. A separate factory class for every class in your system. Ugh.
Automatic factories solve these problems pretty easily. It’s so simple I should have done it a long time ago. Simply have a dependency of type Func<Whatever>. Then you’ll get that delegate injected. When you invoke the delegate, it calls back into the container to Resolve<Whatever>().
If you resolve the dependency with a name, that’s the name the func will use when invoked to do a resolve.
Finally, if your dependency is Func<IEnumerable<Whatever>>, then you’ll get a ResolveAll call executed.
Simple. straightforward, and solves all the problems of coupling, lack of metadata, and boilerplate code.
This is in the drop I just posted yesterday on Codeplex source control – go take a look and let me know what you think!