.NET Core 依赖注入如何处理多个对象

Mic*_*ord 7 .net c# dependency-injection .net-core

正如标题所示,我有一个 .NET Core 应用程序,我正在尝试将其转换为并利用内置的 Microsoft 依赖注入。

我有一个对象和该对象的基类,将其称为CommunicationBaseCommunicator。当我的应用程序启动并读取配置文件时,我可以实例化 N 个对象。

以前,在切换到依赖注入之前,在我的启动例程中的某个位置,我读取配置文件,我将有一个List<CommunicationBase>变量,我将实例化该Communicator变量并向其添加对象,同时设置一些基本属性,这些属性根据关于我的配置中有多少个以及配置中的每个属性。

我如何通过 DI 实现这一目标?

我知道在我的服务中,我会注册该类型,以便可以将其注入到其他类构造函数中。

例如,services.AddTransient<CommunicationBase, Communicator>();但据我了解,这只是用 DI 注册类型。我可以将它注入到一个类中并拥有其中一个的随机实例。

那么我如何拥有 N 个实例,并能够在创建实例时设置每个实例的属性?

或者,这是一种不需要 DI 或 DI 不起作用而我需要按照以前的方式进行的场景吗?

谢谢!

Mic*_*zyn 3

我会稍微修改此处显示的方法。因此,我将定义一些枚举,然后用于决定返回哪个实例。

示例类设置和枚举:

public enum CommuniationType
{
    False, True, Other,
}

public abstract class CommunicationBase
{
    public CommunicationBase(CommuniationType communiationType)
    {
        CommuniationType = communiationType;
    }

    public bool IsConnected { get; set; }
    
    public CommuniationType CommuniationType { get; protected set; }
}

public class Communicator : CommunicationBase
{
    public Communicator(CommuniationType communiationType) : base(communiationType) { }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您有权访问服务集合的地方(例如,在 ASP.NET 中,该地方是Stratup.RegisterServices方法),您定义具体类的对象并注册它们,如下面的示例代码所示(在底部,还有测试使用CommunicationBase对象来测试 puprose 的类):

public class Program
{
    static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        
        SetupNObjects(serviceCollection);

        serviceCollection.AddTransient<CommunicationBaseServiceResolver>(serviceProvider => communicationType =>
        {
            var implementations = serviceProvider.GetServices<CommunicationBase>();
            return implementations.First(x => x.CommuniationType == communicationType);
        });

        serviceCollection.AddScoped<FalseTestClass>();
        serviceCollection.AddScoped<TrueTestClass>();

        var serviceProvider = serviceCollection.BuildServiceProvider();

        var f = serviceProvider.GetService<FalseTestClass>();
        var t = serviceProvider.GetService<TrueTestClass>();
    }
    
    // Here you should take care of registering objects, after reading config.
    // That would be best place to do that.
    static void SetupNObjects(ServiceCollection serviceCollection)
    {
        var comFalse = new Communicator(CommuniationType.False);
        comFalse.IsConnected = false;

        var comTrue = new Communicator(CommuniationType.True);
        comTrue.IsConnected = true;

        serviceCollection.AddScoped<CommunicationBase>((serviceProvider) => comFalse);
        serviceCollection.AddScoped<CommunicationBase>((serviceProvider) => comTrue);
    }
}

public class FalseTestClass
{
    private readonly CommunicationBase communication;

    public FalseTestClass(CommunicationBaseServiceResolver resolver)
    {
        communication = resolver(CommuniationType.False);
    }
}

public class TrueTestClass
{
    private readonly CommunicationBase communication;
    
    public TrueTestClass(CommunicationBaseServiceResolver resolver)
    {
        communication = resolver(CommuniationType.True);
    }
}
Run Code Online (Sandbox Code Playgroud)