Dependency Injection (DI) is a form of Inversion of Control where the instances that one class need are instantiated outside of the class an “injected” into it. The most common injection is constructor injection. This is called inversion of control because the control of the dependencies have been inverted from the dependant class instantiating them to another class instantiating them. e.g. I could write class like this:
Which is perfectly functional, but MyClass is now directly dependant on List
Bear in mind, this is a stupid example. But, it shows inversion of control with types commonly recognizable.
So, I could invert the control on IList
Now MyClass does not have a direct dependency on List
Not a whole lot more complex than before. If I wanted to test MyClass in some way, I could give it a spy:
This is considered Poor Man’s IoC, in that you’re not making use of a framework or a library specifically devoted to IoC.
Yes, you’d never really do this in real life; but it’s a fairly clear example—with commonly-used types.
There’s a plethora of IoC containers for .NET. They’re all great tools, like StructureMap, Autofac, Ninject, Unity, etc. Don’t get me wrong, they’re powerful and they do a lot of things. But, they do a lot of things.
What do I mean by “they do a lot of things”? Well, they’re all effectively designed to work with codebases that are not DI-friendly. They go out of their way to provide features to support DI in any imaginable design. “What’s wrong with that” you say? If you’ve got a brownfield project, that’s great—you can likely get testability with code not designed to be testable—which is a good thing. But, these abilities make us lazy. We stop designing DI-friendly classes because we know how to use a particular IoC container to get a known level of IoC and/or testability. We’ve stopped striving for a simpler design, we’ve stopped striving for DI-friendly code.
If you’re finding that you’re generally using much more than just constructor injection, having reams and reams of config to set up the various instances or lifecycles then you’re probably letting your IoC container do too much for you and your design is suffering. If someone has to spend days understanding your IoC container and it’s config for you project, you may have defeated the purpose.
For lots of good advice on DI in .NET, check out http://blog.ploeh.dk/tags.html#Dependency Injection-ref. Some of my favourites: http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/, http://blog.ploeh.dk/2011/07/28/CompositionRoot/, and http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/