【问题标题】:ASP MVC DependencyResolver with UnityContainer for Unit testing用于单元测试的带有 UnityContainer 的 ASP MVC DependencyResolver
【发布时间】:2017-10-18 15:15:03
【问题描述】:

我正在构建一个 ASP MVC 3 应用程序,在该应用程序中我使用 Unity 作为 IOC 容器,并在 DependencyResolver 上注册它。在我的控制器中,我可以这样做:

DependencyResolver.Current.GetService(GetType(IViewAllPersonsHandler))

然后,当我编写单元测试时,我会在测试中重新定义映射以使用模拟对象。

我的一位同事告诉我,这样做被视为一种反模式。

谁能告诉我是否是这种情况以及为什么?

我知道通常我应该在构造函数中注入我的依赖项,但是随着控制器的增长,构造函数参数变得很长。

谢谢

【问题讨论】:

  • 你不应该从你的控制器调用 DependencyResolver,坚持使用构造函数注入。您的控制器似乎正在做太多事情。您能否将一些依赖项移动到其他层,甚至可能是过滤器或拆分控制器。
  • 我使用的是 CQS 架构,因此对于每个操作我都有一个单独的处理程序或命令(例如:UpdatePersonBankCommand、UpdatePersonAddressCommand...)。我会试试看是否可以拆分控制器,但我不确定是否可以。

标签: c# asp.net-mvc-3 unity-container


【解决方案1】:

大多数人认为服务定位器模式是一种反模式。可能是因为人们可以通过一些腿部工作来解决它。

如果您这样做是为了限制构造函数参数,您可以尝试不同的方法。我使用属性注入。由于我使用的是城堡温莎,默认情况下容器会注入公共属性。最后我看到 Unity 没有这样做,你必须使用一些扩展来让它工作。

除此之外,您可以拆分控制器或委派给操作中的任务。

但我也会远离控制器内部的服务定位器。

HTH

【讨论】:

  • 我已经阅读了这篇关于它的博文blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx;如果我使用属性注入,那么这有什么不同,因为我仍然需要知道控制器上的某个操作使用了哪些依赖项。它可以最大限度地减少问题,但不会让它消失,如果我错了,请纠正我。
  • 依赖不会消失,但对容器的依赖会消失。
  • @Eben Unity 默认不做属性注入,但它不需要任何扩展,它使用属性来装饰属性以进行注入。
  • @frennky --- 啊! unity 可能需要 一个扩展,但如果有记忆的话,有一个可用的,所以没有必要使用属性。我不太喜欢他们的属性:)
  • 大约 18 个月前看过,但看起来像你自己做的事情:) --- stackoverflow.com/questions/515028/…
【解决方案2】:

您可以使用 System.Web.Mvc.DependencyResolver.SetResolver(resovlveDependencyMock);

【讨论】:

    【解决方案3】:

    起订量很容易:

    DependencyResolver.SetResolver(Mock.Of<IServiceLocator>(s => s.GetInstance(It.IsAny<Type>()) == cacheMock.Object));
    

    【讨论】:

    • 能否提供更多细节?我需要什么 NuGet?一个完整的例子会是什么样子?因为只有这些信息我无法让它工作......谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 2013-11-08
    相关资源
    最近更新 更多