Search code examples
asp.net-mvccastle-windsorioc-containersharp-architecture

For specific controller make Windsor instantiate different classes


I use S#arp Architecture which uses Windsor Castle for IoC. I got a new controller now that, unlike all other controllers in the project, need a different implementation of the same interfaces. I.e. all controllers use ProductsRepository: IProductsRepository as implementation, but the new one has to use SpecificProductsRepository.

How do I configure it to recognize and manage this automatically? Either in pure Windsor way, or with ASP.NET MVC help (e.g. in my custom controllers factory).

OK looks like I need subcontainers. Still searching.


Solution

  • An easier and much simpler way would be to use Windsor's service overrides.

    E.g. register your repos like so:

    container.Register(Component.For<IProductsRepository>
                         .ImplementedBy<ProductsRepository>()
                         .Named("defaultProductsRepository"),
                       Component.For<IProductsRepository>
                         .ImplementedBy<SpecificProductsRepository>()
                         .Named("specificProductsRepository"));
    

    which will ensure that the default implementation is ProductsRepository. Now, for your specific controller, add a service override like so:

    container.Register(Component.For<NewController>()
         .ServiceOverrides(ServiceOverride
              .ForKey("productsRepository")
              .Eq("specificProductsRepository"));
    

    You can read the docs here.

    Edit: If you want to register your repositories with AllTypes, you can adjust the registration key e.g. like so:

    container.Register(AllTypes.[how you used to].Configure(c => c.Named(GetKey(c)));
    

    where GetKey e.g. could be something like:

    public string GetKey(ComponentRegistration registration)
    {
        return registration.Implementation.Name;
    }