要根据接口和实现注册一些服务:
services.AddSingleton<IFoo, Foo>();
services.AddSingleton<Foo>(x => x.GetRequiredService<IFoo>());
这确保可以解决IFoo
和Foo
,并且容器将提供相同的实例。
我正在尝试将这个概念扩展到我的用例:
我编写了一个库,它在启动时执行程序集扫描,并自动注册实现的类型IAnalyser
。在客户端代码中,我想解析IEnumerable<IAnalyser>
和FooAnalyser
。
我不确定如何进行注册。这是我目前所拥有的:
IEnumerable<Type> implementationTypes = ScanClientAssembliesForImplementationsOfIAnalyser();
foreach (var implementationType in implementationTypes)
{
services.AddSingleton(typeof(IAnalyser), implementationType); // (1) works
//services.AddSingleton(implementationType); // (2) incorrect
services.AddSingleton(x => /* ...?... */); // (3)
}
(1)中的注册正确地允许我解析IEnumerable<IAnalyser>
。
(2) 中的注册允许我解析FooAnalyser
,但它将是一个不同的实例,因此是不正确的。
我认为正确的方法是通过工厂注册同一个实例。如何在 (3) 中执行此操作?
(请注意,我的上述方法可能是错误的。我想要的只是在客户端代码中解决和IEnumerable<IAnalyser>
。FooAnalyser
也许有完全不同的方法来做到这一点?)
我找到了更简单的解决方案。
有一件好事 - 当你为接口注册实现时,你总是(开箱即用)可以解析
IEnumerable<interface>
以获取所有注册的实现。话虽如此,我们可以循环遍历所有类型,将它们注册为该类型的单例,并使用工厂方法将它们注册为接口实现,如下所示:
我有示例设置:
然后是解决方案(使用最少的 API,但当然也适用于控制器):
我找到了一种解决方法,但我不喜欢它:
似乎对每个分辨率都这样做确实很昂贵。(不过,不可否认的是,如果有某种内置方法可以做我想做的事情,它可能会做类似的事情。)
如果您发现我的方法有误,请告诉我。如果有更好的方法,请添加您的答案,我会接受它。