1

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

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

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

    public class ClassA : IClassA
    {

        public ClassA(IUnityContainer unityContainer)
        {
        }
    }

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

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

4

2 回答 2

8

是的,你应该减少它。

你应该把它减少到0。

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

您应该只使用容器来更轻松地在组合根中组合应用程序:阅读此内容

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

那么,怎样才能减少呢?像这样:

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

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

public class ClassA : IClassA
{
    private readonly IComponent _component;        

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

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

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

我强烈推荐这本书:.NET 中的依赖注入 - Mark Seemann

于 2012-09-14T11:42:51.030 回答
3

您正在做的是滥用容器作为 ServiceLocator。这被认为是现代应用程序架构中的反模式

请改用适当的依赖注入。Martin Fowler对该模式进行了很好的介绍

Mark Seemann 写了一本非常好的书,名为.NET 中的依赖注入

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

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

于 2012-09-14T11:54:29.423 回答