简体   繁体   English

使用Simple Injector解决通用接口

[英]Resolve Generic Interface with Simple Injector

Wondering if it's possible to achieve the following: 想知道是否有可能实现以下目标:

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

So far I haven't been able to. 到目前为止,我还没有。 Here are some code samples: 以下是一些代码示例:

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){
        // ...
    }
}

... given these types/classes I am trying to find something that will allow me to return either ConcreteFacade1 or 2 based on how the container is configured to resolve the interface (which is where I'm having trouble). ...给定这些类型/类我试图找到一些东西,允许我根据容器配置如何解析接口(这是我遇到麻烦的地方)返回ConcreteFacade1或2。

I have tried: 我试过了:

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

resulting in an error stating: IWordFacade<,,,> is not a registered open generic type. 导致错误说明:IWordFacade <,,,>不是注册的开放泛型类型。

The code you supplied is not valid C# and will not compile. 您提供的代码无效C#,无法编译。 You can't specify an open-generic type within the < and > tags. 您无法在<和>标记内指定开放泛型类型。 You have to specify a closed generic type. 您必须指定一个封闭的泛型类型。 The following however is valid C#: 但是以下是有效的C#:

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

Although this would compile, this still will not work in Simple Injector (or any other DI framework), since frameworks always want to return you a concrete instance, but you can't create an instance for an open generic type, which is quite obvious, since an open-generic type is just a template. 虽然这会编译,但这仍然无法在Simple Injector(或任何其他DI框架)中工作,因为框架总是希望返回一个具体的实例,但是你不能为开放的泛型类型创建一个实例,这很明显,因为开放泛型类型只是一个模板。 You need to fill in the blanks to be able to create an instance. 您需要填写空白才能创建实例。 In other words, you need a closed-generic type. 换句话说,您需要一个封闭的泛型类型。

But how should the container know which closed-generic instance it should create given this open generic type? 但是,对于这个开放的泛型类型,容器应该如何知道应该创建哪个封闭通用实例? There is an endless number of possible permutations. 存在无数可能的排列。

Although you can register an open-generic type like this: 虽然您可以注册这样的开放泛型类型:

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

You will have to request for a closed-generic interface for your DI container to be able to resolve it: 您必须为DI容器请求一个封闭的通用接口才能解决它:

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

or 要么

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

UPDATE UPDATE

From your update I understand that there is that you either register ConcreteFacade1 or ConcreteFacade2 , based on the config file, but never both. 根据您的更新,我了解您可以根据配置文件注册ConcreteFacade1ConcreteFacade2 ,但不能同时注册。 To be able to do this (in C#) you need a non-generic interface, otherwise you will only be able to program against System.Object , which is not very useful (and type-safe). 为了能够执行此操作(在C#中),您需要一个非泛型接口,否则您将只能对System.Object进行编程,而System.Object不是非常有用(并且类型安全)。 So let your generic IWordFacade<T1,T2,T3,T4> inherit from the following non-generic interface: 因此,让您的通用IWordFacade<T1,T2,T3,T4>继承自以下非通用接口:

interface IWordFacade {
    object DoSomething(object value);
}

This way you can make the following registration: 这样您就可以进行以下注册:

contianer.Register<IWordFacade, ConcreteFacade1>();

And you can resolve: 你可以解决:

container.GetInstance<IWordFacade>();

Or of course inject IWordFacade into the constructor of a different type. 或者当然将IWordFacade注入到不同类型的构造函数中。

You now need to implement two methods into the implementations. 您现在需要在实现中实现两个方法。 If you have several implementations, it gets useful to define a base class. 如果您有多个实现,那么定义基类会很有用。 This base class can implement the non-generic interface method: 该基类可以实现非泛型接口方法:

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

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

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