[英]How to register two implementations then get one in .Net Core dependency injection
I have parts of my code which depend on more than one implementation of the same interface, and other parts which depend on one of the implementations. 我的部分代码依赖于同一接口的多个实现,以及依赖于其中一个实现的其他部分。
I am registering implementations like: 我正在注册以下实现:
services.AddSingleton<MyInterface, FirstImplementation>();
services.AddSingleton<MyInterface, SecondImplementation>();
Then getting both implementations when needed like: 然后在需要时获得两个实现,如:
var implementations= serviceProvider.GetServices<MyInterface>();
My Issue is when I need one of them, I am trying the following which returns null: 我的问题是当我需要其中一个时,我正在尝试以下返回null:
var firstImplementation= serviceProvider.GetService<FirstImplementation>();
Of course I could use: 我当然可以用:
var implementations= serviceProvider.GetServices<MyInterface>();
foreach (var implementation in implementations)
{
if (typeof(FirstImplementation) == implementation.GetType())
{
FirstImplementation firstImplementation = (FirstImplementation)implementation;
}
}
But I am thinking that I can get my FirstImplementation
directly somehow. 但我想我可以直接以某种方式得到我的FirstImplementation
。
The container knows how to resolve a FirstImplementation
when asked for the MyInterface
, how ever is was not told how to resolve a FirstImplementation
when asked specifically for a FirstImplementation
. 容器知道如何解决FirstImplementation
当被问及为MyInterface
,怎么过就是没有被告知如何解决FirstImplementation
时的特别要求FirstImplementation
。
The built-in services container is meant to serve the basic needs of the framework and most consumer applications built on it. 内置服务容器旨在满足框架的基本需求以及构建在其上的大多数消费者应用程序。 It is bare bones and needs to be configured explicitly to behave as desired. 它很简单,需要明确配置才能按照需要运行。 You will need to also tell it how to get the implementations when explicitly asked for the implementations 在明确要求实现时,您还需要告诉它如何获取实现
//register implementations first
services.AddSingleton<FirstImplementation>();
services.AddSingleton<SecondImplementation>();
//register interfaces using factory that return implementation singleton
services.AddSingleton<MyInterface, FirstImplementation>(p => p.GetService<FirstImplementation>());
services.AddSingleton<MyInterface, SecondImplementation>(p => p.GetService<SecondImplementation>());
So now you can get your FirstImplementation
directly and get the same instance 所以现在你可以直接获得FirstImplementation
并获得相同的实例
var firstImplementation = serviceProvider.GetService<FirstImplementation>();
Actually what you did is not a good practice, You can create two different interfaces inherited from your base interface ( MyInterface ) and then register each implementation corresponding on the proper interface, After that in the part of your code which you need specific implementation you can ask from IoC go give you back specific implementation of your significant interface: 实际上你所做的并不是一个好习惯,你可以创建两个从你的基本接口继承的不同接口 ( MyInterface ),然后在适当的接口上注册相应的每个实现,之后在你需要特定实现的代码部分,你可以从IoC请教,请回复您重要界面的具体实现:
public interface IFirstImplementation:MyInterface {}
public interface ISecondImplementation:MyInterface {}
services.AddTransient<IFirstImplementation, FirstImplementation>();
services.AddTransient<ISecondImplementation, SecondImplementation>();
var firstImplementation= serviceProvider.GetService<IFirstImplementation>();
Microsoft.Extensions.Dependencyinjection
provides the basic needs of Dependency injection, and there's other IoC container
framework available for .NET which can solve your problem. Microsoft.Extensions.Dependencyinjection
提供了依赖注入的基本需求,还有其他可用于.NET的IoC container
框架可以解决您的问题。 For example, you can use Autofac 's Named Services like below: 例如,您可以使用Autofac的命名服务,如下所示:
//registration method
var builder = new ContainerBuilder();
...
builder.RegisterType<FirstImplementation>().Named<MyInterface>("first");
builder.RegisterType<SecondImplementation>().Named<MyInterface>("second");
//resolve method
var firstImplementation = container.ResolveNamed<MyInterface>("first");
For more complicated scenario, you can use Keyed Services which supports resolving with an Index and attributes. 对于更复杂的方案,您可以使用支持使用索引和属性进行解析的密钥服务 。
You also need to pay attention to the instance scope if uses Autofac. 如果使用Autofac,您还需要注意实例范围 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.