我是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;
}
基本上,允许我删除no参数构造函数。这很棒,而且我肯定会实现这一点,但对于所有关于IoC库的炒作来说,它似乎并不是真的那么好。使用Unity作为服务定位器的方式听起来引人注目,但许多人认为这是一种反模式。
所以我的问题是,如果服务找不到问题,并且有一些关于视图和过滤器的DI机会,那么我使用Unity还能获得什么?我只是想确保我没有错过像所有类构造函数的免费DI支持一样精彩的东西。
编辑:
我理解使用Unity DI和MVC控制器的可测试性目的。但我要做的就是添加一个额外的小构造函数,nix Unity,我可以使UnitTest一样。当备选方案更简单时,注册存储库类型和拥有自定义控制器工厂的好处在哪里?替代方案是原生DI。我想我真的想知道除了服务定位之外,Unity(或任何IoC库)的优点还不错。免费的Controller DI真的是我从Unity获得的唯一东西吗?
答案 0 :(得分:1)
一个好的IoC容器不仅可以为您创建具体类,还可以检查该类型与其他类型之间的耦合。如果存在其他依赖项,它将解析它们并创建所需的所有类的实例。
你可以做一些奇特的事情,比如条件绑定。以下是使用Ninject(我的首选IoC)的示例:
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
ninjectKernel.Bind<IValueCalculator>().To<IterativeValueCalculator().WhenInjectedInto<LimitShoppingCart>();
ninject在这里做的是在注入LimitShoppingCart时创建一个IterativeValueCalculator实例,并为任何其他注入创建一个LinqValueCalulator实例。
最大的好处是分离关注(解耦)和可测试性。
答案 1 :(得分:1)
除了测试(这是一个巨大的好处,不应低估),依赖注入允许:
可维护性:只需一次更改即可更改代码行为的功能。
如果您决定在没有依赖注入的情况下更改在所有控制器/服务等上检索用户的类,则需要更新每个构造函数以及正在创建的任何其他随机新实例,前提是您记得每个一个人住。 DI允许您更改一个定义,然后在所有实现中使用。
Scope:使用单行代码,您可以更改实现以创建单例,即仅在每个新Web请求或每个新线程上创建的类</ p>
可读性:依赖注入的使用意味着所有具体类都在一个地方定义。作为开发人员,我可以快速轻松地查看哪些具体类映射到哪些接口,并且知道没有隐藏的实现。这意味着我不仅可以更好地阅读代码,还可以让我有信心根据代码进行开发
设计:我相信使用依赖注入有助于创建设计良好的代码。您自动编写接口代码,您的代码变得更清晰,因为您没有奇怪的代码块来帮助您进行测试
让我们不要忘记......
测试:测试是巨大的!依赖注入允许您测试代码,而无需专门为测试编写代码。好的,你可以创建一个新的构造函数,但是什么阻止了其他人使用该构造函数的目的而不是它的目的。如果另一位开发人员在六个月后出现并将生产逻辑添加到“test”构造函数中会怎样。好的,所以你可以使它internal
,但生产代码仍然可以使用它。为什么给他们选择。
我对IoC框架的体验主要围绕Ninject。因此,上述内容基于我对Ninject的了解,但是相同的原则应该在其他框架中保持相同。
答案 2 :(得分:0)
没有重点是你有一个映射某处指定IUserRepository的具体类型。您可能希望这样的原因是您可以创建一个UnitTest来指定IUserRepository的模拟版本并执行测试而不更改控制器中的任何内容。
答案 3 :(得分:0)
主要是可测试性,但是id建议看Ninject,它与MVC配合得很好。要获得IOC的全部好处,您应该将其与Moq或类似的模拟框架结合起来。
答案 4 :(得分:0)
除了可测试性之外,我认为您还可以添加可扩展性作为其中一个优点。软件开发的最佳实践之一是“使用抽象而不是实现”,虽然您可以通过多种方式完成,但Unity提供了一种非常易于扩展且简单易用的方法。通过使用它,您将创建抽象,定义组件必须遵守的合同。假设您要完全更改应用程序当前使用的存储库。使用DI,您只需“交换”组件,而无需更改应用程序上的单行代码。如果您使用的是硬引用,则可能需要更改并重新编译应用程序,因为它是一个外部组件(在不同的层中)
所以,底线,恕我直言,使用DI可以帮助您在应用程序中拥有可插拔组件并具有SOLID应用程序设计
答案 5 :(得分:0)
关于为什么服务定位器被认为是坏的(有些人)你可以阅读this blog-post by Mark Seeman。
回答你的问题What is so good in Unity
我可以说,除了所有的可测试性,松散耦合和其他等等等等,每个人都在谈论你可以使用像 {{这样的强大功能3}} 允许做一些Unity's Interception事情。我已经在一些最后的项目中使用它并且非常喜欢它。强烈推荐!
P.S。看起来像Castle Windsor
DI容器也有类似的功能(称为拦截器)。其他容器 - 不确定。