我如何注册一个开放的泛型类型,在简单的喷油器的复杂类型的约束? [英] How can i register an open generic type with a complex type constraint in Simple Injector?

查看:127
本文介绍了我如何注册一个开放的泛型类型,在简单的喷油器的复杂类型的约束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个开放的泛型类型 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆