如何根据所需的类注册依赖关系(使用ASP CORE中的内置IOC容器)

问题描述 投票:1回答:2

我试图注册一个接口的不同实现,并根据使用这些实现的类来确定要传递的某个接口。

public interface ITest { }
public class Test1 : ITest { } 
public class Test2 : ITest { }

public class DoSmthWhichCurrentlyNeedsTest1
{
    private ITest test;

    public DoSmthWhichCurrentlyNeedsTest1(ITest test)
    {
        this.test = test;
    }
}

public class DoSmthWhichCurrentlyNeedsTest2
{
    private ITest test;

    public DoSmthWhichCurrentlyNeedsTest2(ITest test)
    {
        this.test = test;
    }
}

当前解决方案:

services.AddTransient(x=>new DoSmthWhichCurrentlyNeedsTest1(new Test1()));
services.AddTransient(x=>new DoSmthWhichCurrentlyNeedsTest2(new Test2()));

这很好用,除非您有一个具有很多依赖关系的类,其中对于构造函数中的每个依赖关系都应调用“ x.GetRequiredService”。

我正在寻找的是这样的:

services.AddTransient<ITest, Test1>
    (/*If ITest is required by DoSmthWhichCurrentlyNeedsTest1*/);
services.AddTransient<ITest, Test2>
    (/*If ITest is required by DoSmthWhichCurrentlyNeedsTest2*/);

我是否还为此错过了其他方式?

c# asp.net-core dependency-injection ioc-container
2个回答
1
投票

这很好用,除非您有一个具有很多依赖关系的类,其中对于构造函数中的每个依赖关系都应调用“ x.GetRequiredService”。

这是ActivatorUtilities.CreateInstance的好用例。这是一个例子:

ActivatorUtilities.CreateInstance

services.AddTransient(sp => ActivatorUtilities.CreateInstance<DoSmthWhichCurrentlyNeedsTest1>(sp, new Test1())); 使用DI容器和您传递的任何其他参数的组合创建指定类型的实例(在此示例中为ActivatorUtilities.CreateInstance<T>)。传入的第一个参数是DoSmthWhichCurrentlyNeedsTest1,并且使用任何其他参数来按类型提供显式值。

在所示的示例中,IServiceProvider将:

  • ActivatorUtilities.CreateInstance寻找合适的构造函数,并分析其参数。
  • 根据可分配的类型,将您作为附加参数提供的任何内容与构造函数参数进行匹配。我们提供可分配给DoSmthWhichCurrentlyNeedsTest1Test1实例,以便在下一步中使用。
  • 通过将参数与您提供的值进行匹配来创建ITest的实例。对于您未提供的任何内容,它将尝试使用DoSmthWhichCurrentlyNeedsTest1来解析DI容器中的值。
  • 这为您提供了不必担心为GetService连接所有DI提供的依赖项的便利,同时仍允许您指定您[[do

关心的那些。

0
投票
这里是一个工作示例,如下所示:
© www.soinside.com 2019 - 2024. All rights reserved.