ASP.NET MVC Web项目中的单元测试类是一个很好的例子吗?

Typ*_*son 6 c# tdd asp.net-mvc dependency-injection

我正在学习TDD.我知道依赖注入,你将类的依赖项放在构造函数的参数中并传入它们,从默认构造函数传递默认实现,例如;

public AccountController() : this( RepositoryFactory.Users())
{
}

public AccountController( IUserRepository oUserRepository)
{
 m_oUserRepository = oUserRepository;
}
Run Code Online (Sandbox Code Playgroud)

RepositoryFactory是一个简单的静态类,它返回当前构建的所选实现

但默认的ASP.NET MVC Web应用程序项目不会这样做,而是DI采用在测试类中的对象初始值设定项中分配的公共属性的形式,例如; 来自AccountController.cs:

protected override void Initialize(RequestContext requestContext)
{
 if (FormsService == null)
  { FormsService = new FormsAuthenticationService(); }
 if (MembershipService == null)
  { MembershipService = new AccountMembershipService(); }

 base.Initialize(requestContext);
}
Run Code Online (Sandbox Code Playgroud)

在测试类AccountControllerTest.cs中:

private static AccountController GetAccountController()
{
 AccountController controller = new AccountController()
 {
  FormsService = new MockFormsAuthenticationService(),
  MembershipService = new MockMembershipService(),
  Url = new UrlHelper(requestContext),
 };
 //snip
}
Run Code Online (Sandbox Code Playgroud)

所以现在我的AccountController类有两种依赖注入方法.我应该使用哪一个?构造函数注入或公共属性?

我在考虑构造函数注入...

ASP.NET MVC是否使用这样的公共属性,因为您需要提供一种特定的注入构造函数的方法,而基本的"创建新"Web应用程序需要通用作为起点?

Mar*_*ann 11

ASP.NET MVC中的示例是如何使用DI的极好演示.

首先,使用默认构造函数和重载构造函数会引入歧义:类是否控制自己的依赖关系,还是从外部获取它们?显然,它无法真正决定.

其次,具有默认实现会引入紧耦合,因为如果没有对它的引用,则无法创建默认实现的新实例.然而,DI全部意义在于能够实现松耦合.

不幸的是,我们很多时候都会看到这个成语.在我的书中,我称之为Bastard Injection反模式 ; 我从奥伦·艾尼(Oren Eini)/艾恩德·拉欣(Ayende Rahien)的许多自以为是的博客文章中提到了这个名字,在那里他走过了一个非常相似的例子.

作为一般建议,我建议在绝大多数情况下使用构造函数注入.它易于实现并具有非常强大的语义:它强制消费者提供依赖关系的实例,有效地说明依赖关系是强制性的.

另一方面,Property Injection意味着依赖项是可选的,因为编译器不会强制您分配值.在大多数情况下,依赖项实际上不是可选的,因此使用此模式应该很少.