Tom*_*Tom 4 .net c# generics unity-container
我的情景看起来(对我来说)很直接,但我找不到解决方案.
我有这种情况
public class Class<T> : IInterface where T : class
{
}
Run Code Online (Sandbox Code Playgroud)
接口不能通用(来自WCF lib.)
所以我想注册这样的界面
container.RegisterType(typeof (IInterface ), typeof (Class<>));
Run Code Online (Sandbox Code Playgroud)
然后用T解决它
我该怎么做?我错过了什么?
我的意图是做类似的事情
container.Resolve<IInterface>(/* specify T */);
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
你错过了一家工厂.
想想看,没有神奇的妖精在背景上工作,猜测你需要的类型.你需要提供它.通过明确说明T配置时的内容如下:
container.RegisterType(
typeof(IInterface),
typeof(Class<SomeType>));
Run Code Online (Sandbox Code Playgroud)
或者通过创建一个T在运行时传递的工厂:
public interface IInterfaceFactory
{
IInterface Create<T>();
}
Run Code Online (Sandbox Code Playgroud)
工厂可以注册如下:
container.RegisterInstance<IInterfaceFactory>(
new InterfaceFactory(container));
Run Code Online (Sandbox Code Playgroud)
实现可以如下所示:
public class InterfaceFactory : IInterfaceFactory
{
private readonly IUnityContainer container;
public InterfaceFactory(IUnityContainer container)
{
this.container = container;
}
public IInterface Create<T>()
{
return this.container.Resolve<Class<T>>();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以将IInterfaceFactory需要使用的消费者注入其中,IInterface并且可以通过调用该Create<T>()方法来请求所需的版本.
UPDATE
如果您认为这是太多代码,您还可以注册工厂代理,如下所示:
container.RegisterInstance<Func<Type, IInterface>>(
type => container.Resolve(
typeof(Class<>).MakeGenericType(type)));
Run Code Online (Sandbox Code Playgroud)
这基本上是相同的,但现在在代表中内联.您的消费者现在可以依赖于Func<Type, IInterface>而不是a IInterfaceFactory并将类型实例传递给委托.
我个人更喜欢使用描述性界面,如IInterfaceFactory.由你决定.
如果没有需要使用非受控端口来解决,你可以让自己的控制界面,使用泛型和不受控制的接口派生.然后,您可以注册open generic并解析封闭的泛型类型.
public interface IControlled<T> : IUncontrolled {}
public class Controlled<T> : IControlled<T> {}
container.RegisterType(typeof(IControlled<>), typeof(Controlled<>));
IUncontrolled instance = container.Resolve<IControlled<string>>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8561 次 |
| 最近记录: |