How do I connect the various pieces of my Web API Castle Windsor DI code so that the Controller\'s routing selects the correct interface implementation?
Note
You should not mix installation vs resolving. IOW your should not have
kernel.AddFacility<TypedFactoryFacility>();
in the WindsorControllerFactory
But the generic container configuration such registering TypedFactoryFacility should be executed in an installer called as earlier as possible.
In order to drive installer execution, you should use an Installer factory
public class YourInstallerFactory : InstallerFactory
{
public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
{
var windsorInfrastructureInstaller = installerTypes.FirstOrDefault(it => it == typeof(WindsorInfrastructureInstaller));
var retVal = new List<Type>();
retVal.Add(windsorInfrastructureInstaller);
retVal.AddRange(installerTypes
.Where(it =>
typeof(IWindsorInstaller).IsAssignableFrom(it) &&
!retVal.Contains(it)
));
return retVal;
}
}
Where windsorInfrastructureInstaller will be somenthing like this
public class WindsorInfrastructureInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
// Resolvers
//container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));
// TypedFactoryFacility
container.AddFacility<TypedFactoryFacility>();
}
}
In your global.asax you'll create&use you installer factory as following
var installerFactory = new YourInstallerFactory();
container.Install(FromAssembly.This(installerFactory));
Your "FrontEnd"(for example the mvc/webapi) project has a folder containing all installers(WindsorInfrastructureInstaller will be one of those) and the installer factory as well or at least that's the way I'm use to organize my solution.
In answer to my own question, I would simply say: There are no shortcakes! Without stopping go or further ado, go here and get this book. Resign yourself to take the time necessary to read it carefully.
So I'm not the only one; here's a quote from Jeff Beck, who wrote that book's foreword: "Often those who start using DI quickly find themselves lost in a sea of confusion."
Don't want to repeat everything again, so just check out my answer on How do I get Web API / Castle Windsor to recognize a Controller?.
As another note - I would advise against doing anything in your repository constructors if you can help it. The reason I say this is that the constructors get called as Windsor is trying to instantiate the correct instance of your repository. What this means is that if any kind of error occurs, it happens as WebApi is trying to create the controller. This can make it a bit tricky to track down the problem sometimes, and also ends up hiding the real issues under tons of layers of exceptions.