简体   繁体   中英

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:

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?

With this exact use-case in mind, DI provides the following method: ActivatorUtilities.CreateInstance
( note the use of 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

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.

2. List of implementations

Register them all as 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

... or just use the ActivatorUtilities which is a way to create the instance directly from a IServiceProvider see Documentation or this other SO question

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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