我如何注册一个开放的泛型类型,在简单的喷油器的复杂类型的约束? [英] How can i register an open generic type with a complex type constraint in Simple Injector?
问题描述
我有一个开放的泛型类型 AccessMessageHandler< TProcess>
我要解决的每一次的 IProcessHandler< AccessMessage< TProcess>>
得到解决。 ?我怎样才能做到这一点。
这是我的代码:
<预类=郎-CS prettyprint-覆盖 >
公共接口IProcess {}
公共接口IProcessHandler<在TProcess>其中,TProcess:IProcess {
无效手柄(TProcess消息);
}
公共类AccessMessage< TProcess> :IProcess哪里TProcess:IProcess {
公共虚拟字符串的用户名{获得;保护套;}
公共虚拟TProcess InnerProcess {搞定;保护套; }
}
公共类AccessMessageHandler< TProcess> :IProcessHandler< AccessMessage< TProcess>>
式TProcess:IProcess {
公共AccessMessageHandler(IProcessHandler< TProcess> innerHandler){}
公共无效手柄(AccessMessage< TProcess>消息){
//访问控制
_innerHandler.Handle(message.InnerProcess)
}
}
公共类JustDoIt:IProcess {
公共虚拟字符串什么{获取;集;}
}
公共类JustDoItHandler:IProcessHandler< JustDoIt> {
公共无效手柄(JustDoIt消息){
//句柄
}
}
我如何注册IProcessHandler,AccessMessageHandler为简单的注射器解决象下面这样:
VAR accessMessageProcess =新AccessMessage< JustDoIt>()
{
用户名=用户,
InnerProcess =新JustDoIt(){什么=XXX}
};
VAR处理器= GetHandlerFor(accessMessageProcess);
//必须返回AccessMessageHandler< JustDoIt>(JustDoItHandler)
handler.Handle(accessMessageProcess);
您可以执行以下报名方式:
container.RegisterManyForOpenGeneric(
的typeof(IProcessHandler<>),
typeof运算(JustDoItHandler).Assembly);
container.RegisterOpenGeneric(
的typeof(IProcessHandler&所述;&1+),
的typeof(AccessMessageHandler&所述;>));
到 RegisterManyForOpenGeneric
通话将搜索组件的 JustDoItHandler
并查找 IProcessHandler<的所有公共混凝土(非通用)实现; TProcess>
。到底这只是一样做了一堆手动调用到 container.Register< IProcessHandler< SomeProcess>中SomeProcessHandler方式>()
到 RegisterOpenGeneric
调用映射一个开放的通用抽象到一个开放的泛型类型。它的背景使用未注册的类型解析,所以每次一个 IProcessHandler< TProcess>
请求未明确注册(使用 RegisterManyForOpenGeneric
的实例),一个 AccessMessageHandler< TProcess方式>
解决(如果泛型类型约束相匹配)
下面的代码可以用来解决对象图并执行处理程序:
VAR处理器= container.GetInstance< IProcessHandler< AccessMessage< JustDoIt>>>();
handler.Handle(accessMessageProcess);
这应该可以解决如下图:
IProcessHandler< AccessMessage< JustDoIt>>处理器=
新AccessMessageHandler&所述; JustDoIt>(
新JustDoItHandler());
请注意,虽然该 AccessMessageHandler< TProcess>
是的不的一个装饰。装饰器包装相同的类型,因为它实现了,但你的 AccessMessageHandler< TProcess>
工具 IProcessHandler< AccessMessage< TProcess>>
但包裹 IProcessHandler< TProcess>
。我认为这种模式正确的名称是代理。
I have an open generic type AccessMessageHandler<TProcess>
which I want to resolve every time that an IProcessHandler<AccessMessage<TProcess>>
is resolved. How can I do this?
This is my code:
public interface IProcess {}
public interface IProcessHandler<in TProcess> where TProcess : IProcess {
void Handle(TProcess message);
}
public class AccessMessage<TProcess> : IProcess where TProcess : IProcess {
public virtual string Username {get;protected set;}
public virtual TProcess InnerProcess { get; protected set; }
}
public class AccessMessageHandler<TProcess> : IProcessHandler<AccessMessage<TProcess>>
where TProcess : IProcess {
public AccessMessageHandler(IProcessHandler<TProcess> innerHandler){}
public void Handle(AccessMessage<TProcess> message){
// access control
_innerHandler.Handle(message.InnerProcess)
}
}
public class JustDoIt : IProcess {
public virtual string What {get;set;}
}
public class JustDoItHandler : IProcessHandler<JustDoIt> {
public void Handle(JustDoIt message) {
// handle
}
}
How can i register IProcessHandler, AccessMessageHandler for Simple Injector resolve like below:
var accessMessageProcess = new AccessMessage<JustDoIt>()
{
Username = "user",
InnerProcess = new JustDoIt() { What="xxx" }
};
var handler = GetHandlerFor(accessMessageProcess);
// must return AccessMessageHandler<JustDoIt>(JustDoItHandler)
handler.Handle(accessMessageProcess);
You can do the following registration:
container.RegisterManyForOpenGeneric(
typeof(IProcessHandler<>),
typeof(JustDoItHandler).Assembly);
container.RegisterOpenGeneric(
typeof(IProcessHandler<>),
typeof(AccessMessageHandler<>));
The call to RegisterManyForOpenGeneric
will search the assembly of the JustDoItHandler
and looks for all public concrete (non-generic) implementations of IProcessHandler<TProcess>
. In the end this is just the same as doing a bunch of manual calls to container.Register<IProcessHandler<SomeProcess>, SomeProcessHandler>()
.
The call to RegisterOpenGeneric
maps an open generic abstraction to an open generic type. It uses unregistered type resolution on the background, so every time a IProcessHandler<TProcess>
is requested that is not registered explicitly (using RegisterManyForOpenGeneric
for instance), an AccessMessageHandler<TProcess>
is resolved (if the generic type constraints match).
The following code can be used to resolve the object graph and execute the handler:
var handler = container.GetInstance<IProcessHandler<AccessMessage<JustDoIt>>>();
handler.Handle(accessMessageProcess);
This should resolve the following graph:
IProcessHandler<AccessMessage<JustDoIt>> handler =
new AccessMessageHandler<JustDoIt>(
new JustDoItHandler());
Do note though that the AccessMessageHandler<TProcess>
is not a decorator. A decorator wraps the same type as it implements, but your AccessMessageHandler<TProcess>
implements IProcessHandler<AccessMessage<TProcess>>
but wraps IProcessHandler<TProcess>
. I think the right name for this pattern is a proxy.
这篇关于我如何注册一个开放的泛型类型,在简单的喷油器的复杂类型的约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!