简体   繁体   English

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

[英]Unity register generic type for non generic interface

my scenario looks (to me) very straight forward, but I couldn't find a resolution. 我的情景看起来(对我来说)很直接,但我找不到解决方案。

I have this scenario 我有这种情况

public class Class<T> : IInterface where T : class
{ 

}

the interface cannot be made generic (coming from WCF lib.) 接口不能通用(来自WCF lib。)

so I want to register the interface like this 所以我想注册这样的界面

container.RegisterType(typeof (IInterface ), typeof (Class<>));

and then resolve it with T 然后用T解决它

How can I do it? 我该怎么做? What am I missing? 我错过了什么?

my intention is doing something like 我的意图是做类似的事情

container.Resolve<IInterface>(/* specify T */);

What am I missing? 我错过了什么?

You are missing a factory. 你错过了一家工厂。

Think about it, there are no magic leprechauns working on the background guessing the type you need. 想想看,没有神奇的妖精在背景上猜测你需要的类型。 You need to supply it. 你需要提供它。 Either by explicitly stating what T is while configuring like this: 通过在配置时明确说明T是这样的:

container.RegisterType(
    typeof(IInterface),
    typeof(Class<SomeType>));

Or by creating a factory where you pass on the T at runtime: 或者通过创建一个在运行时传递T的工厂:

public interface IInterfaceFactory
{
    IInterface Create<T>();
}

The factory can be registered as follows: 工厂可以注册如下:

container.RegisterInstance<IInterfaceFactory>(
    new InterfaceFactory(container));

And an implementation can look as follows: 实现可以如下所示:

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>>();
    }
}

Now you can inject the IInterfaceFactory into consumers that need to work with IInterface and they can request the version they need by calling the Create<T>() method. 现在,您可以将IInterfaceFactory注入需要使用IInterface消费者,他们可以通过调用Create<T>()方法来请求所需的版本。

UPDATE UPDATE

If you think this is too much code, you can also register a factory delegate as follows: 如果您认为这是太多代码,您还可以注册工厂代理,如下所示:

container.RegisterInstance<Func<Type, IInterface>>(
    type => container.Resolve(
        typeof(Class<>).MakeGenericType(type)));

This is basically the same, but now inlined in a delegate. 这基本上是相同的,但现在在代表中内联。 Your consumers can now depend on a Func<Type, IInterface> instead of a IInterfaceFactory and pass a type instance on to the delegate. 您的消费者现在可以依赖于Func<Type, IInterface>而不是IInterfaceFactory ,并将类型实例传递给委托。

I personally prefer the use of a descriptive interface such as IInterfaceFactory . 我个人更喜欢使用IInterfaceFactory等描述性界面。 It's up to you. 由你决定。

If you don't need to resolve using the uncontrolled interface, you can make your own controlled interface which uses generics and derives from the uncontrolled interface. 如果你不需要使用不受控制的接口来解决,你可以让自己的控制界面,使用泛型和不受控制的接口派生。 Then you can register the open generic and resolve the closed generic types. 然后,您可以注册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>>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM