Registercollection打开泛型类型

时间:2017-06-15 11:19:46

标签: c# generics simple-injector

Simple Injector 4可以使用以下内容吗?

var types = container.GetTypesToRegister(typeof(IFoo<>), assemblies);
container.RegisterCollection(typeof(IFoo<>), types);

public interface IFoo<T> where T : IBar { ... }

public interface IBar { ... }

并且在程序集中可以找到类似的类型,如下所示:

public class Foo : IFoo<FooBar> { ... }

,其中

public class FooBar : IBar { ... }

容器验证此注册。但是当我做的时候

container.GetAllInstances<IFoo<IBar>>();

然后结果为空。 我的意图是注入以下内容:

IEnumerable<IFoo<IBar>> foos

我希望返回IFoo<>的所有封闭类型实现,其中封闭的泛型参数是IBar的实现。

另外一点是,无论何时我想为使用IEnumerable<IFoo<IBar>>的服务编写单元测试,我都试图用以下方法模拟这个:

IEnumerable<IFoo<IBar>> collection = new[] { new Foo() };
new ConsumerService(collection);

这里编译器很难将类型Foo转换为IFoo<IBar>,我认为我理解(​​不确定......)。但我不明白的是Simple Injector如何实例化集合中的类型?

1 个答案:

答案 0 :(得分:2)

为了能够实现您想要的效果,您必须制作IFoo<T>界面变体。

您获得空列表的原因是IFoo<IBar>无法从IFoo<FooBar>分配。自己尝试一下:C#编译器不允许你将Foo强制转换为IFoo<IBar>

要实现这一目标,您必须使IFoo<T>协变。换句话说,您需要按如下方式定义接口:

public interface IFoo<out T> { }

完成此操作后,您将看到Simple Injector会根据您的预期自动为您解析所有实例。

对于你来说,拥有out类型参数是否有用是一个不同的问题。鉴于你给出的抽象描述,我无法回答。