Validating Castle Windsor Installers

The Problem

If you’ve ever used Castle Windsor, chances are you’ve run into the lovely problem of having misconfigured or missing dependencies. The worst part is that we don’t see these issues until runtime. Even worse is that it’s possible to entirely miss one of these errors and have them potentially make it out to clients!

Chances are you’ve also wondered if there is a way to programmatically validate your dependencies either in your tests, when your application starts up, or perhaps even at compile time. Ponder no longer!

The Solution

While it’s not a silver bullet (yet), below is a method that you can add to tests or your application to make sure that all of your registered classes can be resolved.

Note: I originally was trying to solve this problem and found this solution on StackOverflow. I’ve modified the code a bit to now handle some error cases.

Where can I use this?

Ideally, this would happen at compile time and I believe that that’s possible with Roslyn where we are able to add compiler extensions. Until then, the best places are going to be two locations:

  • Your app start up. Most likely, that’s going to be your AppStart.cs, however, it’s going to be wherever you create your IWindsorContainer.
  • Your unit tests! We may not be able to create build errors (yet), but what we can do is fail our unit tests if the dependencies don’t resolve. Most unit tests have their own WindsorInstaller file separate from the installer file in the actual application. You would have to actually create an instance of the WindsorInstaller from your application to verify that the application, not your tests, is configured properly.

Important Notes

  • This will not tell you when topmost level classes are not registered. This will only work when you have classes registered with an installer / container and then check the dependencies. For example, if you register no classes, then Castle Windsor will have no dependencies to check for, thus, the method I have provided will return successfully.
  • The first time you start using this test, you may notice configuration errors when you expected none. Chances are, those errors are because you have some classes that have dependencies that you manually resolve or don’t have Castle Windsor resolve. There are a few ways to fix this.
    • Use TypedFactories for your factories
    • Make sure that all of your classes can be automatically resolved, meaning that all dependencies can be resolved without having to be constructed manually. Tricky parameters such as those that must be provided at run time  should either be re-architected or you may optionally use inline / dynamic dependencies in Castle Windsor.
    • If you have the case where some code is never automatically resolved with Castle Windsor, then you can also use SubResolvers to tell Castle Windsor that an interface is resolvable and that you’ll handle it manually.
      • Take this following code as an example

In the Install method, we’re telling Castle Windsor that the IBar and IBuzz interfaces are indeed resolvable. Then, in the Resolve method, we’re doing nothing. Wut? This is because typically you would expect to set up how to resolve those interfaces in the Resolve method, but here in our case, we’re not because we know for certain that Castle Windsor will never automatically resolve these interfaces; rather, we manually instantiate these classes via our own factory classes. While this does work, I am still investigating on whether or not there is a better way to do this.