【问题标题】:How to reduce amount of passing IUnityContainer object through constructors?如何减少通过构造函数传递的 IUnityContainer 对象的数量?
【发布时间】:2012-09-14 11:40:34
【问题描述】:

我有一个很大的类层次结构。 当我的应用程序启动时,我初始化 UnityContainer 对象并对其进行配置。 之后,我总是通过构造函数将它传递给层次结构中的另一个类。 像这样:

Unity 容器将这些类作为注册:IClassA、IClassB、IClassC、IClassD

接口的所有具体实现都有带有 IUnityContainer 参数的构造函数。 例如,

    public class ClassA : IClassA
    {

        public ClassA(IUnityContainer unityContainer)
        {
        }
    }

因此,每次创建某个类的新实例时,我都必须传递一个 IUnityContainer 对象。

我可以减少传递 IUnityContainer 对象作为构造函数参数的数量吗? 也许通过使用依赖属性?

【问题讨论】:

  • 为什么要将容器传递给构造函数?这是一种非常糟糕的代码气味。

标签: c# .net dependency-injection inversion-of-control unity-container


【解决方案1】:

是的,你应该减少它。

你应该把它减少到 0。

像这样使用 DI 容器是一种不好的做法。不要把 DI 容器当成一个神奇的超级工厂。

您应该只使用容器来更轻松地在 composition root 编写您的应用程序:read this

您的代码不应意识到它是由 DI 容器组成的,容器只是一种技术,而 DI 是一种技术。您也应该能够在没有容器的情况下编写应用程序。

那么,如何减少呢?像这样:

public class ClassA : IClassA
{
    public ClassA()
    {
    }
}

如果您的ClassA 需要某些东西(依赖项、接口),那么您应该通过构造函数注入它。

public class ClassA : IClassA
{
    private readonly IComponent _component;        

    public ClassA(IComponent component)
    {
        _component = component;
    }
}

您也可以使用其他注入模式:属性注入、方法注入、环境上下文。

如果您使用问题中的容器,那么您将隐藏实际类的所有依赖项。您无法弄清楚该实际类需要做什么,因为它将使用容器来临时解决某些问题。它完全反对依赖注入,因为你没有注入依赖,你只是注入了一个通用工厂(你可以要求任何东西),这是非常危险的,而且毫无意义地增加了复杂性。

我强烈推荐这本书:Dependency Injection in .NET - Mark Seemann

【讨论】:

  • 我知道这种方法是一种不好的做法。你有什么推荐给我的?
  • 是的,没关系。谢谢。我开始阅读 Mark Seemann 的《.NET 中的依赖注入》一书:)
【解决方案2】:

您正在做的是滥用容器作为 ServiceLocator。这被认为是anti-pattern in modern application architecture

改为使用适当的依赖注入。 Martin Fowler 给了一个good introduction on the pattern

Mark Seemann 就该主题写了一本非常好的书,名为 Dependency Injection in .NET

正如@PeterPorfy 已经指出的那样,组合根的概念很重要。您在那里向您的容器注册所有依赖项,然后通过在那里解析您的应用程序或服务的根对象来启动。

您永远不会将容器交给该组合根之外的类!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2017-04-19
    相关资源
    最近更新 更多