Unity DI在MVC中的好处是什么?
本文关键字:是什么 DI MVC Unity | 更新日期: 2023-09-27 18:07:04
我对Unity和IoC有点陌生,但不熟悉MVC。我一直在阅读和阅读关于使用Unity与MVC和唯一真正有用的事情,我一直看到的是获得免费DI与控制器的能力。
从这个开始:
public HomeController() : this(new UserRepository())
{
}
public HomeController(IUserRepository userRepository)
{
this.UserRepository = userRepository;
}
:
public HomeController(IUserRepository userRepository)
{
this.UserRepository = userRepository;
}
基本上,允许我删除无参数构造函数。这很好,我肯定会实现它,但它看起来并没有那么好,对于所有关于IoC库的宣传来说。使用Unity作为服务定位器听起来很有吸引力,但许多人认为这是一种反模式。
所以我的问题是,服务定位的问题和一些DI机会与视图和过滤器,还有什么我从使用Unity获得的?我只是想确保我没有错过一些美妙的东西,比如对所有类构造函数的免费DI支持。
编辑:我理解使用Unity DI与MVC控制器背后的可测试性目的。但我需要做的只是添加一个额外的构造函数,nix Unity,我就可以进行UnitTest了。注册存储库类型并拥有自定义控制器工厂的最大好处是什么?另一种选择是本地DI。我想我真的很想知道Unity(或任何IoC库)除了服务定位之外还有什么伟大之处。免费的控制器DI真的是我从Unity得到的唯一东西吗?
一个好的IoC容器不仅可以为您创建具体的类,还可以检查该类型与其他类型之间的耦合。如果有额外的依赖项,它会解析它们并创建所需的所有类的实例。
你可以做一些奇特的事情,比如条件绑定。下面是一个使用Ninject(我喜欢的IoC)的例子:
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
ninjectKernel.Bind<IValueCalculator>().To<IterativeValueCalculator().WhenInjectedInto<LimitShoppingCart>();
ninject在这里做的是在注入到LimitShoppingCart时创建一个IterativeValueCalculator的实例,在其他注入时创建一个linqvaluecalculator的实例。
最大的好处是关注点分离(解耦)和可测试性。
关于为什么服务定位器被一些人认为是不好的,你可以阅读Mark Seeman的博客文章。
回答你的问题What is so good in Unity
,我可以说,除了所有的可测试性,松散耦合和其他blah-blah-blah-s,每个人都在谈论你可以使用像Unity的拦截这样的很棒的功能,它允许做一些aop之类的事情。我在最近的一些项目中使用过它,并且非常喜欢它。强烈推荐!
注。似乎Castle Windsor
DI容器也有类似的功能(称为拦截器)。其他容器——不确定。
除了测试(这是一个巨大的好处,不应该低估),依赖注入允许:
可维护性:通过一次修改改变代码行为的能力。
如果你决定在没有依赖注入的情况下改变在所有控制器/服务等中检索用户的类,你需要更新每个构造函数和任何其他正在创建的随机新实例,只要你记得每个实例的位置。DI允许您更改一个定义,然后在所有实现中使用。
作用域:用一行代码你可以改变你的实现来创建一个单例,一个类只在每个新的web请求或每个新的线程上创建
可读性:使用依赖注入意味着所有的具体类都在一个地方定义。作为一名参与项目的开发人员,我可以快速轻松地准确地看到哪些具体类映射到哪些接口,并且知道没有隐藏的实现。这意味着我不仅可以更好地阅读代码,而且使我有信心针对代码进行开发
Design:我相信使用依赖注入有助于创建设计良好的代码。你自动编写接口代码,你的代码变得更干净,因为你没有奇怪的代码块来帮助你测试
让我们不要忘记…
测试:测试是巨大的!依赖注入允许您测试代码,而不必专门为测试编写代码。好吧,你可以创建一个新的构造函数,但是如何阻止其他人将这个构造函数用于其他目的呢?如果六个月后另一个开发人员出现并将生产逻辑添加到您的"测试"构造函数中,该怎么办?好的,所以你可以让它成为internal
,但这仍然可以用于生产代码。为什么要给他们选择权呢?
我使用IoC框架的经验主要是围绕Ninject。因此,以上是基于我对Ninject的了解,但是相同的原则应该在其他框架中保持相同。
不,主要的一点是您在某处有一个映射,它指定了IUserRepository的具体类型。你可能喜欢那个的原因是你可以创建一个UnitTest它指定IUserRepository的模拟版本并执行你的测试而不改变控制器中的任何东西。
主要是可测试性,但我建议看看Ninject,它与MVC配合得很好。要获得IOC的全部好处,您应该将其与Moq或类似的mock框架结合起来。
除了可测试性之外,我认为您还可以将可扩展性作为优点之一。软件开发的最佳实践之一是"处理抽象,而不是实现",虽然你可以通过多种方式做到这一点,但Unity提供了一种非常可扩展和简单的方法来实现这一点。通过使用它,您将创建定义组件必须遵守的契约的抽象。假设您希望完全更改应用程序当前使用的存储库。使用DI,您只需"交换"组件,而不需要更改应用程序中的一行代码。如果您使用硬引用,您可能需要更改和重新编译您的应用程序,因为它的外部组件(在不同的层中)
所以,底线,我的意思是,使用DI可以帮助你在应用程序中拥有可插入的组件,并拥有一个坚实的应用程序设计