Composition Root Reuse by Mark Seemann
A Composition Root is application-specific. It makes no sense to reuse it across code bases.
At regular intervals, I get questions about how to reuse Composition Roots. The short answer is: you don't.
Since it appears to be a Frequently Asked Question, it seems that a more detailed answer is warranted.
Composition Roots define applications #
A Composition Root is application-specific; it's what defines a single application. After having written nice, decoupled code throughout your code base, the Composition Root is where you finally couple everything, from data access to (user) interfaces.
Here's a simplified example:
public class CompositionRoot : IHttpControllerActivator { public IHttpController Create( HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { if(controllerType == typeof(ReservationsController)) { var ctx = new ReservationsContext(); var repository = new SqlReservationRepository(ctx); request.RegisterForDispose(ctx); request.RegisterForDispose(repository); return new ReservationsController( new ApiValidator(), repository, new MaƮtreD(10), new ReservationMapper()); } // Handle more controller types here... throw new ArgumentException( "Unknown Controller type: " + controllerType, "controllerType"); } }
This is an excerpt of a Composition Root for an ASP.NET Web API service, but the hosting framework isn't particularly important. What's important is that this piece of code pulls in objects from all over an application's code base in order to compose the application.
The ReservationsContext class derives from DbContext; an instance of it is injected into a SqlReservationRepository object. From this, it's clear that this application uses SQL Server for it data persistence. This decision is hard-coded into the Composition Root. You can't change this unless you recompile the Composition Root.
At another boundary of this hexagonal/onion/whatever architecture is a ReservationsController, which derives from ApiController. From this, it's clear that this application is a REST API that uses ASP.NET Web API for its implementation. This decision, too, is hard-coded into the Composition Root.
From this, it should be clear that the Composition Root is what defines the application. It combines all the loosely coupled components into an application: software that can be executed in an OS process.
It makes no more sense to attempt to reuse a Composition Root than it does attempting to 'reuse' an application.
Container-based Composition Roots #
The above example uses Pure DI in order to explain how a Composition Root is equivalent to an application definition. What about DI Container-based Composition Roots, then?
It's essentially the same story, but with a twist. Imagine that you want to use Castle Windsor to compose your Web API; I've already previously explained how to do that, but here's the IHttpControllerActivator implementation repeated:
public class WindsorCompositionRoot : IHttpControllerActivator { private readonly IWindsorContainer container; public WindsorCompositionRoot(IWindsorContainer container) { this.container = container; } public IHttpController Create( HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { var controller = (IHttpController)this.container.Resolve(controllerType); request.RegisterForDispose( new Release( () => this.container.Release(controller))); return controller; } private class Release : IDisposable { private readonly Action release; public Release(Action release) { this.release = release; } public void Dispose() { this.release(); } } }
Indeed, there's no application-specific code there; this class is completely reusable. However, this reusability is accomplished because the container is injected into the object. The container itself must be configured in order to work, and configuration code is just as application-specific as the above Pure DI example.
Thus, with a DI Container, you may be able to decouple and reuse the part of the Composition Root that performs the run-time composition. However, the design-time composition is where you put the configuration code that select which concrete types should be used in which cases. This is the part that specifies the application, and that's not reusable.
Summary #
Composition Roots aren't reusable.
Sometimes, you might be building a suite of applications that share a substantial subset of dependencies. Imagine, for example, that you're building a REST API and a batch job that together solve a business problem. The Domain Model and the Data Access Layer may be shared between these two applications, but the boundary isn't. The batch job isn't going to need any Controllers, and the REST API isn't going to need whatever is going to kick off the batch job (e.g. a scheduler). These two applications may have a lot in common, but they're still different. Thus, they can't share a Composition Root.
What about the DRY principle, then?
Different applications have differing Composition Roots. Even if they start with substantial amounts of duplicated Composition Root code, in my experience, the 'common' code tends to diverge the more the applications are allowed to evolve. That duplication may be accidental, and attempting to eliminate it may increase coupling. It's better to understand why you want to avoid duplication in the first place.
When it comes to Composition Roots, duplication tends to be accidental. Composition Roots aren't reusable.
Comments
In the example where the domain layer and the data access layer are shared between applications, it really depends whether they will have a future need to be wired differently according to the application.
If that's not the case, you could argue that there's no need for two components either.
One solution would be to use a Facade which internally wires them up and exposes it as a single interface. This allows for reuse of the domain and the DAL as a single component, opaque to the client.
Kenneth, thank you for writing. If you create a Facade that internally wires up a Domain Model and DAL, you've created a tightly coupled bundle. What if you later discover that you need to instrument your DAL? You can't do that if you prematurely compose object graphs.
Clearly, there are disadvantages to doing such a thing. What are the advantages?
Dear Mark,
Thank you for another excellent post.
Some of the composition roots I wrote became really large, too, especially the more complex the application got. In these cases I often introduced factories and builders that created parts of the final object graph and the imperative statements in the composition root just wired these subgraphs together. And this leads me to my actual question:
What do you think about pushing these factories and builders to a library so that they can be reused by different composition roots? This would result in much less code that wires the object graph. I know that abstract factories belong to the client, but one could provide Simple Factories / Factory Methods or, even better I think, the Builder Pattern is predestined for these situations, because it provides default dependencies that can be exchanged before the Build method is called.
If I think about automated tests, I can see that the concept I just described is already in use: every test has an arrange phase which in my opinion is the composition root for the test. To share arrange code between tests, one can use e.g. builders or fixture objects (or of course AutoFixture ;-) ). This reduces the code needed for the arrange phase and improves readability.
What is your opinion on pushing Simple Factories / Builders to a reusable library?
With regards,
Kenny
In the production environment, the service is deployed as a Windows Service, but for easier testing and development, we also have a console application that hosts the same service. Both entry points are basically the same composition root and should use the same components. We want to share the composition root, because otherwise when a component needs a new dependency and a constructor parameter is added, we'd have to change the same code in two different places.
Kenny, Daniel, thank you for writing. In an attempt to answer your questions, I wrote a completely new blog post on the subject; I hope it answers some of your questions, although I suppose you aren't going to like the answer.
If you truly have a big Composition Root, it may be one of the cases where you should consider adopting a DI Container with a convention-based configuration.
Another option is to make your 'boundary library' (e.g. your UI, or your RESTful endpoints) a library in itself, and host that library in various contexts. The Composition Root resides in that boundary library, so various hosts can 'reuse' it, as they reuse the entire application. You can see an example of this in my Outside-In Test-Driven Development Pluralsight course.
Dear Mark, thank you for writing the other blog post. Now I finally have time to answer.
I think in our specific situation there is a subtle but important difference: Rather than reusing a composition root between two libraries, we essentially have two different ways of hosting the same library (and thus composition root). One is used primarily during development, while the other is used in production, but essentially they are (and always will be) the same thing. So in my opinion it would even be dangerous to not use the same composition root here, as it would just add a source of errors if you change the dependency graph setup in one project but forget to do so in the other.
But I guess this is what you meant with creating a boundary library, isn't it?
Daniel, if I understand you correctly, that's indeed the same technique that I demonstrate in my Outside-In Test-Driven Development Pluralsight course. Although it may only be me splitting hairs, I don't consider that as reusing the Composition Root as much as it's deploying the same application to two different hosts; one of the hosts just happens to be a test harnes :)