I've been using Dependency Injection (DI) for a while, injecting either in a constructor, property, or method. I've never felt a need to use an Inversion of Control (IoC) container. However, the more I read, the more pressure I feel from the community to use an IoC container.
I played with .NET containers like StructureMap, NInject, Unity, and Funq. I still fail to see how an IoC container is going to benefit / improve my code.
I'm also afraid to start using a container at work because many of my co-workers will see code which they don't understand. Many of them may be reluctant to learn new technology.
Please, convince me that I need to use an IoC container. I'm going to use these arguments when I talk to my fellow developers at work.
In my opinion the number one benefit of an IoC is the ability to centralize the configuration of your dependencies.
If you're currently using Dependency injection your code might look like this
If you used a static IoC class, as opposed to the, IMHO the more confusing, configuration files, you could have something like this:
Then, your Static IoC class would look like this, I'm using Unity here.
IoC Containers are also good for loading deeply nested class dependencies. For example if you had the following code using Depedency Injection.
If you had all of these dependencies loaded into and IoC container you could Resolve the CustomerService and the all the child dependencies will automatically get resolved.
For example:
Because all the dependencies are clearly visible, it promotes creating components which are loosely coupled and at the same time easily accessible and reusable across the application.
So, it's been almost 3 years, eh?
50% of those who commented in favor of IoC frameworks don't understand the difference between IoC and IoC Frameworks. I doubt they know that you can write code without being deployed to an app server
If we take most popular Java Spring framework, it is IoC configuration moved from XMl into the code and now look like this
`@Configuration public class AppConfig {
} ` And we need a framework to do this why exactly?
Honestly I don't find there to be many cases where IoC containers are needed, and most of the time, they just add unneeded complexity.
If you are using it just for making construction of an object simpler, I'd have to ask, are you instantiating this object in more than one location? Would a singleton not suit your needs? Are you changing the configuration at runtime? (Switching data source types, etc).
If yes, then you might need an IoC container. If not, then you're just moving the initialization away from where the developer can easily see it.
Who said that an interface is better than inheritance anyway? Say you're testing a Service. Why not use constructor DI, and create mocks of the dependencies using inheritance? Most services I use only have a few dependencies. Doing unit testing this way prevents maintaining a ton of useless interfaces and means you don't have to use Resharper to quickly find the declaration of a method.
I believe that for most implementations, saying that IoC Containers remove unneeded code is a myth.
First, there's setting up the container in the first place. Then you still have to define each object that needs to be initialized. So you don't save code in initialization, you move it (unless your object is used more than once. Is it better as a Singleton?). Then, for each object you've initialized in this way, you have to create and maintain an interface.
Anyone have any thoughts on this?
I've found that correctly implementing Dependency Injection tends to force programmers to use a variety of other programming practices that help to improve the testability, flexibility, maintainability, and scalability of code: practices like the Single Responsibility Principle, Separations of Concerns, and coding against APIs. It feels like I'm being compelled to write more modular, bite-sized classes and methods, which makes the code easier to read, because it can be taken in bite-sized chunks.
But it also tends to create rather large dependency trees, which are far more easily managed via a framework (especially if you use conventions) than by hand. Today I wanted to test something really quickly in LINQPad, and I figured it'd be too much bother to create a kernel and load in my modules, and I ended up writing this by hand:
In retrospect, it would have been quicker to use the IoC framework, since the modules define pretty much all of this stuff by convention.
Having spent some time studying the answers and comments on this question, I am convinced that the people who are opposed to using an IoC container aren't practicing true dependency injection. The examples I've seen are of practices that are commonly confused with dependency injection. Some people are complaining about difficulty "reading" the code. If done correctly, the vast majority of your code should be identical when using DI by hand as when using an IoC container. The difference should reside entirely in a few "launching points" within the application.
In other words, if you don't like IoC containers, you probably aren't doing Dependency Injection the way it's supposed to be done.
Another point: Dependency Injection really can't be done by hand if you use reflection anywhere. While I hate what reflection does to code navigation, you have to recognize that there are certain areas where it really can't be avoided. ASP.NET MVC, for example, attempts to instantiate the controller via reflection on each request. To do dependency injection by hand, you would have to make every controller a "context root," like so:
Now compare this with allowing a DI framework to do it for you:
Using a DI framework, note that:
ISimpleWorkflowInstanceMerger
, I can test that it gets used the way I anticipate, without the need for a database connection or anything.ISimpleWorkflowInstanceMerger
interface. This allows me to break the application up into separate modules, and maintain a true multi-tier architecture, which in turn makes things much more flexible.A typical web application will have quite a few controllers. All of the pain of doing DI by hand in each controller will really add up as your application grows. If you have an application with only one context root, which never tries to instantiate a service by reflection, then this isn't as big a problem. Nevertheless, any application that uses Dependency Injection will become extremely expensive to manage once it reaches a certain size, unless you use a framework of some kind to manage the dependency graph.