c# - 服务定位器比依赖注入(inject)更容易使用?

标签 c# dependency-injection ioc-container autofac

我正在处理的应用程序依赖 Autofac 作为 DI 容器,而让我决定使用它的原因之一是委托(delegate)工厂功能(参见 here)

这适用于我需要多次重新创建相同元素的所有情况,就像某些报告和相关屏幕的情况一样。一些报告(甚至是相同类型的报告)是同时执行的,但它们仅通过用户定义的参数进行更改,因此(我认为)注入(inject)工厂以创建实例、传递自由参数并将其余的留给申请。

问题在于每个报告都由数量可变的子报告(任务)组成,并且每个任务都实现一个 ITask 接口(interface)。每个报表最多可以使用 50 个不同的任务,每个任务都封装了一个精确的业务操作。我的一个选择是注入(inject)委托(delegate)工厂并在需要时创建它们。

这些任务必须由工厂动态生成,例如:

var myTaskA = _taskFactoryConcreteTaskA();
var myTaskB = _taskFactoryConcreteTaskB();
var myTaskC = _taskFactoryConcreteTaskC();
...
var myTaskZZ = = _taskFactoryConcreteTaskZZ();

需要大量手动连接(委托(delegate)、构造函数、支持字段等),而类似

var myTaskA = _taskFactory.Create<ConcreteTaskA>();
var myTaskB = _taskFactory.Create<ConcreteTaskB>();
var myTaskC = _taskFactory.Create<ConcreteTaskC>();
...
var myTaskZZ = _taskFactory.Create<ConcreteTaskZZ>();

工作量会少得难以置信,特别是如果 _taskFactory 包装容器,如 this other post 所示。 ,但这也基本上意味着我正在使用服务定位器来创建我的任务。

我还有哪些适合解决此问题的其他选择?

(注意:很有可能我完全偏离了正轨,我必须阅读更多有关 DI 的内容,在这种情况下,任何贡献都会更加重要)

最佳答案

由于问题中指出的工厂不接受任何参数,因此使用工厂有Leaky Abstraction 的味道。正如 Nicholas Blumhardt 在他的回答中指出的那样,更好的方法可能是简单地将每个任务注入(inject)消费者。

在这种情况下,由于所有任务都实现相同的接口(interface),而不是注入(inject)多达 50 个不同的 ITask 实例,您可以组合它们:

public class MyConsumer
{
    private readonly IEnumerable<ITask> tasks;

    public MyConsumer(IEnumerable<ITask> tasks)
    {
        this.tasks = tasks;
    }

    public void DoSomething()
    {
        foreach (var t in this.tasks)
        {
            // Do something with each t
        }
    }
}

或者,您可以将 ITasks 序列组合成 Composite ,这实际上是我的首选解决方案:

public CompositeTask : ITask
{
    private readonly IEnumerable<ITask> tasks;

    public CompositeTask(IEnumerable<ITask> tasks)
    {
        this.tasks = tasks;
    }

    // Implement ITask by iterating over this.tasks
}

这将简化消费者并将要执行多个任务的事实转化为实现细节:

public class MyConsumer
{
    private readonly ITask task;

    public MyConsumer(ITask task)
    {
        this.task = task;
    }

    public void DoSomething()
    {
        // Do something with this.task
    }
}

关于c# - 服务定位器比依赖注入(inject)更容易使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8086026/

相关文章:

c# - 如何为 VisualStudio2015 设置 .NET 版本(代码)

c# - 在不创建新类的情况下反序列化字符串列表?

c# - Web Api .net 框架 4.6.1 和 identityServer4

c# - ASP.NET Core 中的高级依赖注入(inject)

c# - LightInject IoC 容器在解析类型时抛出 stackoverflow

dependency-injection - 使用 IoC 和循环引用解决此问题的最佳设计是什么

c# - 编译器选择错误的重载调用 IEquatable<T>.Equals

javascript - 为什么我的构造函数参数私有(private)类成员在运行时未定义?

asp.net-mvc - 如何正确使用Moq框架——基本问题

c# - Autofac 运行时参数