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);
}));