Unity注册非泛型接口的泛型类型

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)

Ste*_*ven 8

我错过了什么?

你错过了一家工厂.

想想看,没有神奇的妖精在背景上工作,猜测你需要的类型.你需要提供它.通过明确说明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.由你决定.


Tyl*_*sen 8

如果没有需要使用非受控端口来解决,你可以让自己的控制界面,使用泛型和不受控制的接口派生.然后,您可以注册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)