How to use dependency injection in enterprise projects

architecture, c#, dependency-injection, inversion-of-control

Solution

First of all, Dependency Injection is a design pattern that does not require a container. The DI pattern states:

Dependency injection is a software design pattern that allows a choice of component to be made at run-time rather than compile time

Take for example Guice (java dependency injection framework), in Java Guice is a DI framework but it is not a container itself.

Most of the DI tools in .Net are actually containers, so you need to populate the container in order to be able to inject the dependency

I do not like the idea to have to register every component every time in a container, I simply hate that. There are several tools that help you auto register components based on conventions, I do not use Unity, but I can point you for example to Ninject or AutoFac

I am actually writing a small utility to auto register components based on conventions using practically any DI tool, it is still in dev phase

About your questions:

Should there be a "general container" that can be used for bootstrapping, accessible as a Singleton?

The answer is yes, (there's a tool to abstract the DI tool used, it is called ServiceLocator) that's how DI tools work, there is a static container available to the application, however, it is not recommended to use it inside the domain objects to create instances, that's considered an anti-pattern

BTW I have found this tool really useful to register components at runtime:

http://bootstrapper.codeplex.com/

Should a container be passed around, where all instances can RegisterInstance?

No. that would violate the law of Demeter. If you decide to use a container is better to register the components when the application starts

How can the container be made accessible when needed

Well using the Common Service Locator you could use it anywhere in your application, but like I said, it is not recommended to use it inside the domain objects to create the required instances, instead, inject the objects in the constructor of the object and let the DI tool to automatically inject the correct instance.

Now based on this:

Constructor injection seems false, controverse of being the standard way, you have to pass down interfaces from a component level to the very down where it is used right on startup, or a reference is hold ending up in a "know where you live" antipattern

Makes me think that you are not writing unit tests heavily for your application which is bad. So my suggestion is, before choosing between which DI tool you are going to use, or before taking all the answers you get to this question into consideration, refer to the following links which are focus on one thing: Write clean testable code, this is by far the best source you could get to answer yourself your own question

Clean Code talks:

http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded

http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded

Articles

http://misko.hevery.com/2010/05/26/do-it-yourself-dependency-injection/

http://misko.hevery.com/code-reviewers-guide/

Previous link in PDF http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf

The following links are super highly recommended

http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

http://www.loosecouplings.com/2011/01/how-to-write-testable-code-overview.html

Problem

Imagine you have an application with several hundreds of classes implementing dozens of "high level" interfaces (meaning component level). Is there a recommend way of doing dependecy injection (like with unity). Should there be a "general container" that can be used for bootstrapping, accessible as a Singleton? Should a container be passed around, where all instances can RegisterInstance? Should everything be done by RegisterType somewhere in the startup? How can the container be made accessible when needed. Constructor injection seems false, controverse of being the standard way, you have to pass down interfaces from a component level to the very down where it is used right on startup, or a reference is hold ending up in a "know where you live" antipattern. And: having a container "available" may bring developers to the idea of resolving server components in client context. how to avoid that? Any discussion welcome! edit for clarification I figured out a somewhat realworld example to have a better picture of what problems i see. lets imagine the application is a hifi system. the system has cd player (integrated in a cd-rack) and an usb port (integrated in an usb rack) to play music from. now, the cd player and the usb port shall be able to play mp3 music. i have an mp3 decoder somewhere around, which is injectable. now i start the hifi system. there is no cd inserted yet and no usb stick pluged in. i do not need a mp3 decoder now. but with constructor injection, i have to already inject the dependency into the cd rack and the usb rack. what if i never insert a mp3 cd or an mp3 usb stick? shall i hold an reference in the cd rack, so when an mp3 cd is inserted, i have a decorder on hand? (seems wrong to me) the decoder is needed in a subsystem of the cd rack, which is only started if a mp3 gets inserted. now i have no container in the cd rack, what about constructor injection here?

Original source