We have around 20 self-contained projects in our solution. Each project is a stand-alone component and has its own Windsor installer. With this structure, we are finding our Windsor installers becoming large, unmanageable and brittle.
In our solution, some over-arching projects depend on a subset of other smaller projects, and some projects depend on another.
A diagram of the structure would be similar to this, where arrows indicate dependencies:
Don't dwell on the naming of each item in the diagram. They're just different projects which are separated for manageability and reuse concerns.
The two approaches I can see for the Windor installation is:
Each component installs its dependencies. In this example, the API's installer installs Component A and Component B. Likewise, Component A's installer installs Module A and Module B, and Component B's installer installs module B and Module C. This is my preferred solution as it provides neat encapsulation.
The top-level project installs all dependencies in the solution. In this example, the API's installer installs both Component A and B, and all three modules.
The down-side of the first approach is that each installer which may be installed more than once needs to use Component.For<X>.OnlyNewServices()
for each registration. This is verbose and easy to forget and really needs to be applied to every single registration to allow for application growth and component reuse.
The down-side of the second approach is that the projects end up requiring knowledge of components which they have no concern knowing about, and encapsulation is broken.
Questions:
Is there a way in Windsor to set default behaviour so components may be registered multiple times?
Alternatively, is there some other recommended Windsor architecture for non-trivial dependencies (for example, sub-containers)?
I have resolved this elegantly by using Windsor's built in assembly scanning. Each project now only installs the components defined in the project, doesn't explicitly install any other installers and doesn't eagerly resolve components from other assemblies.
The API project contains:
var container = new WindsorContainer();
container.Install(FromAssembly.InThisApplication());
Part of the reason for our unmanageable installers is that some installers were doing early resolution of dependent components. This is an anti-pattern and enforces installer order. Removing this need makes application-wide installation trivial.