Some time ago I decided that Autofac was my IOC of choice. After spending a few years using Unity I knew I wanted more and, after evaluating a few libraries, Autofac fitted how I work.
Aside from the usual property and constructor injection stuff we would expect from any IOC library, Autofac has quite a few additional features that can make coding life a lot easier. And in less lines of code.
One thing I love to show people who have used IOC for a while is my use of delegate factories.
The wiki post from the Autofac project is here: https://github.com/autofac/Autofac/wiki/Delegate-Factories.
I think the title says it all!
Let components create instances of other components without hand-coding factories.
So, in short, we can use Autofac as a factory and take a dependency on that factory instead of the type itself. This is quite powerful as it means we can create instances of our dependency within our component as needed.
This can be a little hard to wrap your head around so my example use case is to combine this with IDisposable. The concept, now, is that we have a component that we need to inject but that has some expensive resource we need to use and dispose of in a very short, controlled manner.
To achieve this we simply:
- Register our component with the container (preferably using a module)
- Create our delegate factory that returns an instance of our component
- Update our main code to have a dependency one the factory
Finally, we update the delegate factory to return Owned<T> (where T is your type) which instructs Autofac that you want to take ownership of the resolved instance.
At this point its worth noting that I haven’t taken a dependency on the container. I could do this and achieve something similar by creating a nested lifetime scope or service locating the component. I tend to avoid having a dependency on the container directly as then my code is tied to whatever IOC implementation I have and makes my mock my container interfaces in my unit tests. Service locating the component is something I strongly believe you should only do when you can’t rely on the IOC integration to automatically build up your dependencies for you (so rare). Aside from anything else you’ve just made your code rely on one big factory so its less decoupled.
I’ve put a sample gist on Github and I’ve used additional code so that I can call with Func<T>. This lets me resolve by type rather than by name as in the wiki link above. It also opens up scope for messing around with constructor parameters and the like.
The gist is here: https://gist.github.com/simonproctor/6047835
I also took inspiration from these links which you may find useful:
As always if there are subtle bugs, issues and so on then let me know and I’ll update the
gist (and this post if need be).