Home > Enterprise >  Register multiple implementations of generic interface in Castle Windsor
Register multiple implementations of generic interface in Castle Windsor

Time:08-30

I want to register an implementation for my service IQueryService<TEntity, TPrimaryKey>.

So I have code that looks like this:

IocManager.IocContainer.Register(Component.For(typeof(IQueryService<,>))
    .ImplementedBy(typeof(QueryService<,,,>);

And I want to create a similar implementation for entities with string as primary key, let's call it QueryServiceString. Is there a way to write it down so that Castle Windsor will automatically pick up which class it should inject?

IocManager.IocContainer.Register(Component.For(typeof(IQueryService<,STRING?>))
    .ImplementedBy(typeof(QueryServiceString<,,>)

CodePudding user response:

A partially open generic type IQueryService<,STRING?> is invalid syntax.

You can register a factory method and resolve a type based on the generic arguments:

IocManager.IocContainer.Register(Component.For(typeof(QueryService<,>)));
IocManager.IocContainer.Register(Component.For(typeof(QueryServiceString<>)));

IocManager.IocContainer.Register(Component.For(typeof(IQueryService<,>))
    .UsingFactoryMethod((kernel, creationContext) =>
    {
        Type type = null;

        var tEntity = creationContext.GenericArguments[0];
        var tPrimaryKey = creationContext.GenericArguments[1];
        if (tPrimaryKey == typeof(string))
        {
            type = typeof(QueryServiceString<>).MakeGenericType(tEntity);
        }
        else
        {
            type = typeof(QueryService<,>).MakeGenericType(tEntity, tPrimaryKey);
        }

        return kernel.Resolve(type);
    }));
  • Related