如何注册两个实现,然后在.Net Core依赖注入中获得一个

Yah*_*ein 11 c# dependency-injection .net-core

我的部分代码依赖于同一个接口的多个实现,以及依赖于其中一个实现的其他部分.

我正在注册以下实现:

services.AddSingleton<MyInterface, FirstImplementation>();
services.AddSingleton<MyInterface, SecondImplementation>();
Run Code Online (Sandbox Code Playgroud)

然后在需要时获得两个实现,如:

var implementations= serviceProvider.GetServices<MyInterface>();
Run Code Online (Sandbox Code Playgroud)

我的问题是当我需要其中一个时,我正在尝试以下返回null:

var firstImplementation= serviceProvider.GetService<FirstImplementation>();
Run Code Online (Sandbox Code Playgroud)

我当然可以用:

var implementations= serviceProvider.GetServices<MyInterface>();
foreach (var implementation in implementations)
{
    if (typeof(FirstImplementation) == implementation.GetType())
    {
        FirstImplementation firstImplementation = (FirstImplementation)implementation;
    }
}
Run Code Online (Sandbox Code Playgroud)

但我想我可以FirstImplementation 直接以某种方式得到我.

Moh*_*esh 6

实际上你所做的并不是一个好的做法,你可以创建从基接口(MyInterface )继承的两个不同的接口,然后在正确的接口上注册对应的每个实现,之后在你需要特定实现的代码部分中你可以向 IoC 询问,返回重要接口的具体实现:

执行

public interface IFirstImplementation:MyInterface {}
public interface ISecondImplementation:MyInterface {}
Run Code Online (Sandbox Code Playgroud)

注册

services.AddTransient<IFirstImplementation, FirstImplementation>();
services.AddTransient<ISecondImplementation, SecondImplementation>();
Run Code Online (Sandbox Code Playgroud)

用法

var firstImplementation= serviceProvider.GetService<IFirstImplementation>();
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好主意。纯粹为了 DI 目的而创建的空接口会带来代码异味并且会使代码膨胀,因为所有实现都将具有相应的接口,甚至无需扩展基本接口。 (2认同)

Nko*_*osi 5

容器知道如何解决FirstImplementation何时提出的问题MyInterface,怎么都没有被告知如何解决FirstImplementation何时专门解决的问题FirstImplementation

内置服务容器旨在满足框架和基于其构建的大多数消费者应用程序的基本需求。它是裸露的骨头,需要进行显式配置才能表现出所需的行为。当明确要求实现时,您还需要告诉它如何获取实现。

//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>());
Run Code Online (Sandbox Code Playgroud)

所以现在您可以FirstImplementation直接获取并获得相同的实例

var firstImplementation = serviceProvider.GetService<FirstImplementation>();
Run Code Online (Sandbox Code Playgroud)

  • @YahyaHussein 检查更新的答案,既然问题已经得到澄清,应该可以解决问题。 (3认同)