将 IUnityContainer 注入控制器 class 以节省额外代码是一种好习惯吗

Is it good practice to inject IUnityContainer into controller class to save extra code

我在我的控制器中使用以下内容

IAccountRepository AcctRep;
IAccountProductRepository AcctProdRep;

public HomeController(IUnityContainer container)
{
    AcctRep = container.Resolve<IAccountRepository>();
    AcctProdRep = container.Resolve<IAccountProductRepository>();
}

在我的 UnityConfig.cs AppStart 文件中..

container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
      WithMappings.FromMatchingInterface,
      WithName.Default);

为什么?

  1. 为了避免在 UnityConfig.cs 中手动注册大约 30 个不同的存储库,如下所示:

    container.RegisterType< IAccountRepository, AccountRepository >();

  2. 为了省去在无数控制器中进行以下操作的麻烦

    IAccountRepository AcctRep;
    IAccountProductRepository AcctProdRep;
    
    public HomeController(IAccountRepository acctRep, IAccountProductRepository acctProdRep)
    {
        AcctRep = acctRep;
        AcctProdRep = acctProdRep;
    }
    

并且因为我提出的建议看起来比上面更整洁(想象一下必须注入 4 个存储库)...

问题 是我有太多的性能问题,还是我没有看到并且将来会后悔的任何事情?

编辑 这个问题的一小部分类似于建议的重复项,但不完全是。即Unity 的 AllClasses 映射的使用和执行上述操作对性能的影响与正常注入以及如果我这样做的话我将来可能会遇到的问题。@Konamiman 的回答方法非常简洁,让问题看看其他人必须做什么说..

我会说这不是一个好主意,因为它会损害代码的可维护性。您正在创建 classes 与依赖注入引擎的强耦合,如果您将来决定停止使用 Unity 并(例如)切换到 Autofac 怎么办?它还 损害代码可读性 ,因为 class 依赖项是什么并不明显。

所以正确的方法是:

  1. 在 class 构造函数中传递依赖项。乍一看似乎很麻烦,但它会导致代码更具可读性和可维护性,并且 您应该始终重视代码的可读性而不是您自己编写时间的便利性。此外,如果你发现自己在构造函数中传递了太多参数,也许是时候审查你的设计了(你的控制器是不是做的太多了?也许它应该依赖于业务 class 而不是直接依赖于四个存储库.. .?)

  2. 至少,如果您仍想将依赖项解析器传递给您的 classes,创建依赖项解析器的抽象,以便您被隔离来自使用的具体引擎。像这样的东西应该足以开始:

.

interface IDependencyResolver
{
    T Resolve<T>();
}

然后您可以为 Unity 创建并注册 class 的实现,如果需要,可以轻松替换它。