Composition Root by Mark Seemann
In my book I describe the Composition Root pattern in chapter 3. This post serves as a summary description of the pattern.
The Constructor Injection pattern is easy to understand until a follow-up question comes up:
Where should we compose object graphs?
It's easy to understand that each class should require its dependencies through its constructor, but this pushes the responsibility of composing the classes with their dependencies to a third party. Where should that be?
It seems to me that most people are eager to compose as early as possible, but the correct answer is:
As close as possible to the application's entry point.
This place is called the Composition Root of the application and defined like this:
A Composition Root is a (preferably) unique location in an application where modules are composed together.
This means that all the application code relies solely on Constructor Injection (or other injection patterns), but is never composed. Only at the entry point of the application is the entire object graph finally composed.
The appropriate entry point depends on the framework:
- In console applications it's the Main method
- In ASP.NET MVC applications it's global.asax and a custom IControllerFactory
- In WPF applications it's the Application.OnStartup method
- In WCF it's a custom ServiceHostFactory
(you can read more about framework-specific Composition Roots in chapter 7 of my book.)
The Composition Root is an application infrastructure component.
Only applications should have Composition Roots. Libraries and frameworks shouldn't.
The Composition Root can be implemented with Poor Man's DI, but is also the (only) appropriate place to use a DI Container.
A DI Container should only be referenced from the Composition Root. All other modules should have no reference to the container.
Using a DI Container is often a good choice. In that case it should be applied using the Register Resolve Release pattern entirely from within the Composition Root.
Read more in Dependency Injection in .NET.