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

时间:2015-06-23 06:36:45

标签: c# inversion-of-control unity-container ioc-container

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

IAccountRepository AcctRep;
IAccountProductRepository AcctProdRep;

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

并在AppStart中的UnityConfig.cs文件中。

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;
    }
    
  3. 并且因为我提议看起来比上面更整洁(想象必须注入4个存储库)...

    问题我是否有太多的性能问题,或者我未看到的任何事情以及将来会后悔的事情?

    修改 这个问题的一小部分类似于建议的重复但不完全.. I.e.使用Unity的AllClasses映射和执行上述操作对正常注入的性能影响以及我将来可能会遇到的问题如果我这样下去的话。@ Konamiman的答案是非常整洁的问题,看看其他人有什么说..

1 个答案:

答案 0 :(得分:1)

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

所以正确的方法是:

  1. 在类构造函数中传递依赖项。一开始看起来似乎很麻烦,但它会带来更易读和可维护的代码,并且您应该始终支持代码可读性超过您自己的写入时间便利性。此外,如果您发现自己在构造函数中传递了太多参数,或许是时候审查您的设计了(您的控制器是否做得太多了?也许它应该依赖于业务类而不是直接依赖于四个存储库.. ?)

  2. 至少,如果您仍希望将依赖项解析程序传递给类,创建依赖项解析程序的抽象,以便您与使用的具体引擎隔离。这样的事情应该足够开始:

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

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