简体   繁体   English

同一类 C# 和 .NET Core 的多个依赖项注入

[英]Multiple dependency injections for same class C# and .NET Core

I have an interface我有一个界面

public interface ITest
{
    void SayHello();
}

And it's implemented as它被实现为

public class Test : ITest
{
    Test(string type)
    {
        // Do Something with type
    }

    public void SayHello()
    {
        // 
    }
}

Register it in the DI as:将其在 DI 中注册为:

services.AddScoped<ITest, Test>();

I need to create two instance with these conditions:我需要创建两个具有这些条件的实例:

Test t1 = new Test("ABC");
Test t2 = new Test("XYZ");

How I can achieve this using DI?如何使用 DI 实现这一目标?

With this exact use-case in mind, DI provides the following method: ActivatorUtilities.CreateInstance考虑到这个确切的用例,DI 提供了以下方法: ActivatorUtilities.CreateInstance
( note the use of ITest vs Test ) 注意使用ITest vs Test

Test t1 = 
    ActivatorUtilities
        .CreateInstance<Test>("ABC");

Test t2 = 
    ActivatorUtilities
        .CreateInstance<Test>("XYZ");

There are several options how you can implement it.有几个选项可以实现它。

1. Factory 1.工厂

Create a factory for generating the instance you need:创建一个工厂来生成您需要的实例:

public TestFactory : ITestFactory
{
   public ITest Create(string type)
   {
       return new Test(type);
   }
}

And register just the factory只注册工厂

services.AddScoped<ITestFactory, TestFactory>();

Advantage you have the single piece of code the ITestFactory which can be mocked and the whole logic how the instance and which instance is create resides there.优点是您拥有可以模拟的ITestFactory的单段代码以及如何创建实例和创建哪个实例的整个逻辑。

2. List of implementations 2. 实现列表

Register them all as ITest将它们全部注册为ITest

services.AddScoped<ITest>(sp => new Test("ABC"));
services.AddScoped<ITest>(sp => new Test("XYZ"));

... and then use it in a class like this: ...然后在这样的类中使用它:

public class Consumer 
{
   public Consumer(IEnumerable<ITest> testInstances)
   {
       // This is working great if it does not matter what the instance is and you just need to use all of them.
   }
}

3. ActivatorUtilities 3. ActivatorUtilities

... or just use the ActivatorUtilities which is a way to create the instance directly from a IServiceProvider see Documentation or this other SO question ...或者只是使用ActivatorUtilities ,这是一种直接从IServiceProvider创建实例的方法, 请参阅文档或其他SO 问题

var serviceProvider = <yourserviceprovider>;
var test1 = ActivatorUtilities.CreateInstance<Test>(sp, "ABC");
var test2 = ActivatorUtilities.CreateInstance<Test>(sp, "XYZ");

But like it is also written in the comment of your question it really depends what you want to do with both instances and where do you get the string type from.但就像它也写在你的问题的评论中一样,它真的取决于你想对这两个实例做什么以及你从哪里获得string type

You can also do more advanced ways with a combination of option 1 and 2 but therefore the better description of your problem and usage is needed.您还可以结合选项 1 和 2 执行更高级的方法,但因此需要更好地描述您的问题和用法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM