使用simpleinjector注册opengeneric
本文关键字:opengeneric 注册 simpleinjector 使用 | 更新日期: 2023-09-27 18:00:23
我有以下类:
public interface IDbCommandHandler<in TCommand, out TOutput>
where TCommand : IDbCommand
{
TOutput Handle(TCommand command);
}
public class SubIdentifierItemCreateCommand<TItemType, TDefaultValues>
: BaseDbCommand
where TItemType: TDefaultValues
{
}
public class SubIdentifierItemCreateCommandHandler<TItemType, TDefaultValues>
: BaseDbCommandHandler<SubIdentifierItemCreateCommand<TItemType, TDefaultValues>, TItemType>,
IDbCommandHandler<SubIdentifierItemCreateCommand<TItemType, TDefaultValues>, TItemType>
where TItemType: class, TDefaultValues, IItemForGenericItemByIdentifierRetriever , new()
{
}
我需要将SubIdentifierItemCreateCommandHandler
注册为singleton开放泛型,以处理对类型为的服务的任何请求CCD_ 2。
这可能吗?我尝试过各种方法,但总是会出错。
_container.RegisterSingleOpenGeneric(
typeof(IDbCommandHandler<,>),
typeof(SubIdentifierItemCreateCommandHandler<,>));
_container.RegisterOpenGeneric(
typeof(IDbCommandHandler<,>),
typeof(SubIdentifierItemCreateCommandHandler<,>));
// this one is throws a compile-time error, that you cannot
// use partial open types.
_container.RegisterManyForOpenGeneric(
typeof(IDbCommandHandler<SubIdentifierItemCreateCommand<,>,>),
typeof(SubIdentifierItemCreateCommandHandler<,>));
我希望能够拨打以下电话并工作:
var item = _container.GetInstance<
IDbCommandHandler<
SubIdentifierItemCreateCommand<
SectionData,
ISectionDataDefaultValues>,
SectionData>>();
不幸的是,您在框架中偶然发现了一个错误。Simple Injector 1.6.1无法正确处理"where TItemType:TDefault Values"约束。
解决方案很简单,可以迁移到simple Injector 2.0(通过NuGet)。
如果出于某种原因无法切换到Simple Injector 2.0,则可以注册ResolveUnregisteredType
事件来注册类型,以解决1.6.1版本中的错误:
container.ResolveUnregisteredType += (sender, e) =>
{
var serviceType = e.UnregisteredServiceType;
if (serviceType.IsGenericType &&
serviceType.GetGenericTypeDefinition() == typeof(IDbCommandHandler<,>))
{
var commandArg = serviceType.GetGenericArguments()[0];
var outputArg = serviceType.GetGenericArguments()[1];
if (commandArg.IsGenericType &&
commandArg.GetGenericTypeDefinition() ==
typeof(SubIdentifierItemCreateCommand<,>))
{
var itemTypeArgument = commandArg.GetGenericArguments()[0];
var defaultValuesArgument = commandArg.GetGenericArguments()[1];
if (itemTypeArgument != outputArg)
{
return;
}
Type typeToRegister;
try
{
typeToRegister =
typeof(SubIdentifierItemCreateCommandHandler<,>)
.MakeGenericType(itemTypeArgument.GetGenericArguments());
}
catch (ArgumentException)
{
// Thrown by MakeGenericType when the type constraints
// do not match. In this case, we don't have to register
// anything and can bail out.
return;
}
object singleInstance = container.GetInstance(typeToRegister);
// Register the instance as singleton.
e.Register(() => singleInstance);
}
}
};
我知道,这很难看,但至少还有一个工作要做;-)