DI dotnet/C#: 在构造函数中解析具有(不同)字符串的对象

DI dotnet/C#: Resolve objects with (different) strings in constructor

我有一个使用 Configuration、DependencyInjection 和 Hosting 的 .Net 控制台应用程序,我需要在其中创建多个对象,其中每个对象都不同,具体取决于传递的字符串。

class Program
{
    static void Main(string[] args)
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", false)
            .Build();

        serviceCollection.AddSingleton<IMyService, MyService>();
        serviceCollection.AddSingleton<IOtherService, OtherService>();
        serviceCollection.AddTransient<IMyObject, MyObject>();
        ...


public class MyObject : IMyObject
{
    public string _aString {get; set;}

    public MyObject(string aString)
    {
        _aString = aString;
    }
}


public class MyService : IMyService
{
    private IMyObject _objectA;
    private IMyObject _objectB;
    private readonly IOtherService _otherService;
    private readonly IOptions<FilePaths> _filePaths;

    public MyService(IOtherService otherService, IOptions<FilePaths> filePaths)
    {
        _otherService = otherService;
        // file path options contains 2 different file path strings
        _filePaths = filePaths;
    }

    public void WorkWithObjects()
    {
        // Instantiate Objects depending on File Path Strings
        // Do some work with my objects here
    }
}

每个字符串都是定义对象的文件路径,但我在上面的示例中抽象了行为。

解决此问题的最佳方法是什么?我的设计正确吗?
我做了一些研究并尝试:

首先,无需在 DI 容器中注册 MyObject:serviceCollection.AddTransient<IMyObject, MyObject>(); 因为您计划根据配置拥有多个 'MyObject' 实例。我假设您可以在配置中有多个文件路径。

引入单独的 IMyObjectsFactory 界面非常好并且不违反任何规则。工厂的唯一职责是创建 IMyObject 的实例。当 IMyObject 实现改变时改变工厂实现是完全没问题的。您将 MyObject 的创建抽象为工厂。

public interface IMyObjectsFactory
{
    IEnumerable<IMyObject> Create();
}

public class MyObjectFactory : IMyObjectsFactory
{
    private readonly IOptions<FilePaths> _filePaths;

    public MyObjectFactory(IOptions<FilePaths> filePaths)
    {
         _filePaths = filePaths;
    }

    public IEnumerable<IMyObject> Create()
    {
        foreach(var path in _filePaths.Value.Paths)
        {
            yield return new MyObject(path)
        }
    }
}