编程语言
首页 > 编程语言> > c#-使用简单注入器解析通用接口

c#-使用简单注入器解析通用接口

作者:互联网

想知道是否有可能实现以下目标:

container.GetInstance<IWordFacade<,,,>>();

到目前为止,我还没有做到.以下是一些代码示例:

IWordFacade<T1,T2,T3,T4>{
    T1 DoSomething(T2);
}

public class ConcreteFacade1 : IWordFacade<int,long,double,decimal>{
    int DoSomething(long param){
        //....
    }
}

public class ConcreteFacade2 : IWordFacade<short,string,float,char>{
    short DoSomething(string param){
        // ...
    }
}

…考虑到这些类型/类,我试图根据容器配置为解析接口的方式(这就是我遇到的麻烦),找到可以使我返回ConcreteFacade1或2的东西.

我努力了:

container.Register(typeof(IWordFacade<,,,>), typeof(ConcreteFacade1));

导致显示错误:IWordFacade< ,,,>.不是注册的开放通用类型.

解决方法:

您提供的代码不是有效的C#,并且不会编译.您不能在<中指定开放通用类型.和>标签.您必须指定一个封闭的泛型类型.但是,以下是有效的C#:

container.GetInstance(typeof(IWordFacade<,,,>));

尽管可以编译,但仍不能在Simple Injector(或任何其他DI框架)中使用,因为框架始终希望返回一个具体实例,但是您无法为开放的泛型类型创建实例,这很明显,因为开放通用类型只是模板.您需要填写空白才能创建实例.换句话说,您需要一个封闭的泛型类型.

但是,在给定这种开放泛型类型的情况下,容器如何知道应该创建哪个封闭泛型实例呢?可能的排列有无数种.

尽管您可以注册像这样的开放通用类型:

container.Register(typeof(IWordFacade<,,,>), typeof(WordImpl<,,,>));

您将需要为您的DI容器请求一个封闭的通用接口,以便能够解决它:

container.GetInstance<IWordFacade<Foo, Bar, FooBar>>();

要么

container.GetInstance(typeof(IWordFacade<Foo, Bar, FooBar>));

更新

从您的更新中,我了解到您是根据配置文件注册ConcreteFacade1或ConcreteFacade2的,但不会两者都注册.为了能够做到这一点(在C#中),您需要一个非通用接口,否则您将只能针对System.Object进行编程,这不是很有用(且类型安全).因此,让您的通用IWordFacade< T1,T2,T3,T4>从以下非通用接口继承:

interface IWordFacade {
    object DoSomething(object value);
}

这样,您可以进行以下注册:

contianer.Register<IWordFacade, ConcreteFacade1>();

您可以解决:

container.GetInstance<IWordFacade>();

或者当然将IWordFacade注入其他类型的构造函数中.

现在,您需要在实现中实现两种方法.如果您有多个实现,则定义基类会很有用.该基类可以实现非通用接口方法:

public abstract class WordFacadeBase<T1, T2, T3, T4> : IWordFacade<T1, T2, T3, T4> {
    public abstract T1 DoSomething(T2 value);
    object IWordFacade.DoSomething(object value) {
        return DoSomething(T2)value);
    }
}

标签:generics,dependency-injection,c,simple-injector
来源: https://codeday.me/bug/20191122/2056008.html