Search code examples
c#genericsdependency-injectioninversion-of-controlcastle-windsor

In Castle Windsor, how to register ONE of many implementations of generic interface for ALL found implementations of generic type?


Having interfaces...

IThing
IWrapping<IThing>

... implemented by Things...

Cookie    : IThing
Carmel    : IThing
Chocolate : IThing

... and Wrappings for them...

Paper <TThing> : IWrapping<TThing> where TThing is IThing
Foil  <TThing> : IWrapping<TThing> where TThing is IThing

... I choose one implementation of Wrapping to run the application with, ignoring the other. To register chosen Wrapping for all known implementations of IThing I currently must list all of them:

Component.For<IWrapping<Cookie>>()   .ImplementedBy<Paper<Cookie>>(),
Component.For<IWrapping<Carmel>>()   .ImplementedBy<Paper<Carmel>>(),
Component.For<IWrapping<Chocolate>>().ImplementedBy<Paper<Chocolate>>(),

How does one register all of them at once?

Component.For<IWrapping<IThing>>()
    .ImplementedBy<Paper<ALL_FOUND_IMPLEMENTATIONS_OF_ITHING>>(), // One place to switch between Paper and Foil

Solution

  • Because you're dealing with generic type parameters within Castle, you can't use the fluent syntax exactly as you've been using it.

    What you can do is the following one-liner:

    container.Register(Component.For(typeof(IWrapping<>)).ImplementedBy(typeof(Paper<>)));
    var cookieWrapper = container.Resolve<IWrapping<Cookie>>();
    

    Upon resolving the dependency, you will get the following result:

    Screenshot of the result upon resolving the wrapper

    This is based on the following object dependency setup (I mirrored what you put in your post but just wanted to make sure you get the full picture of what I've done to reproduce this):

    public interface IThing {}
    public interface IWrapping<IThing> {}
    public class Paper<TThing> : IWrapping<TThing> where TThing : IThing {}
    public class Cookie : IThing {}
    public class Carmel : IThing{}
    public class Chocolate : IThing{}