Recently, I caught wind of a discussion about use or overuse of Inversion of Control and Dependency Injection. One small team was quite religious about using it, while another was, let's say, a bit more circumspect. It made me think about where I would put IoC into the pantheon of silver bullets...
Inversion of Control is a good pattern. You get more testable components and it reinforces good design. IoC does not replace good design. That said, the problems you can solve with IoC, while important, are a small subset of really big issues. It is perfectly appropriate to care about using IoC patterns, and I’m a fan of Spring.Net and Unity. However, IoC can only solve a small number of problems. Its value is specific to the context in which it is applied.
When should it be used, and when should it be avoided?
All quality attributes must be examined with each effort. How reliable is the software? How secure is the software? How maintainable? Gabriel Morgan does a good job of describing 12 quality attributes that he thinks are important in this blog… and I quote him often.
To everything, there is a tradeoff. IoC is very useful for software that is carefully crafted by hand and operates in an environment where limited and secure access to the environment is absolutely insured. If you have a configuration file that controls the application, and a bit of malware works its way onto the box, a simple change to a config file can inject truly nasty functionality directly into an application. Imagine that your application is an e-commerce web site, and the malware hijacks credit card info simply by changing the config file, thus inserting itself into the exe! If the system is to be installed on the client machine, this problem becomes, if anything, worse. This is because your name is on the “front” of the application, while anyone else’s code can be running in the guts, without any way for the user to “remove the add-on.” It may not be acting as an add-on at all. A malicious change to the config file can replace huge swaths of functionality, in a way that can be quite difficult to detect. So, I’d say that IoC is a maintainability item with a solid tradeoff with application security.
IoC also has a complexity tradeoff. Applications that are wired together with IoC may not be the easiest to understand or debug. If every single class has to be injected, then you have added a layer of complexity to the coding and debugging effort. Sure, you can train folks around that, but it is a tradeoff, and one that you have to consider. I remember a “fad” where every class had to have a factory, because using the ‘new’ keyword was evil. I also remember IT dev managers complaining that they had to spend double on a maintenance cycle to rip out about 80% of the factories because they added complexity for classes that were never reused.
I love IoC, but I’m not religious about it. I use it sparingly, to inject major sections of code into an executable. I do believe it is very easy to overuse IoC. Think of it like over-the-counter pain medicine: take a little and a head ache goes away, but don’t overdose.