我正在学习 TDD。我知道依赖注入(inject),你可以将类的依赖项放在构造函数的参数中并让它们传入,从默认构造函数传入默认实现,例如;
public AccountController() : this( RepositoryFactory.Users())
{
}
public AccountController( IUserRepository oUserRepository)
{
m_oUserRepository = oUserRepository;
}
RepositoryFactory 是一个简单的静态类,它返回为当前构建选择的实现
但是默认的 ASP.NET MVC web 应用程序项目不会这样做,相反,DI 采用在测试类的对象初始值设定项中分配的公共(public)属性的形式,例如;来自 AccountController.cs :
protected override void Initialize(RequestContext requestContext)
{
if (FormsService == null)
{ FormsService = new FormsAuthenticationService(); }
if (MembershipService == null)
{ MembershipService = new AccountMembershipService(); }
base.Initialize(requestContext);
}
在测试类 AccountControllerTest.cs 中:
private static AccountController GetAccountController()
{
AccountController controller = new AccountController()
{
FormsService = new MockFormsAuthenticationService(),
MembershipService = new MockMembershipService(),
Url = new UrlHelper(requestContext),
};
//snip
}
所以现在我的 AccountController 类有两种依赖注入(inject)方法。我应该使用哪一个?构造函数注入(inject)还是公共(public)属性?
我在考虑构造函数注入(inject)...
ASP.NET MVC 之所以这样使用公共(public)属性,是因为您需要提供一种注入(inject)构造函数的特定方法,并且基本的“新建”Web 应用程序需要通用作为起点吗?
最佳答案
ASP.NET MVC 中的示例很好地演示了如何不使用 DI。
首先,使用默认构造函数和重载构造函数会引入歧义:类是控制自己的依赖项,还是从外部获取依赖项?显然,它不能真正决定。
其次,拥有默认实现会引入紧耦合,因为您无法在没有引用的情况下创建默认实现的新实例。然而,whole point of DI is to enable loose coupling .
不幸的是,我们经常看到这个成语。在 my book我称之为 Bastard Injection 反模式;我从 Oren Eini/Ayende Rahien 中提取了名称的许多自以为是的博客文章,其中 he walks through a very similar example .
作为一般性建议,我建议在绝大多数情况下使用构造函数注入(inject)。它易于实现并且具有很强的语义:它强制消费者提供依赖项的实例,有效地说明依赖项是强制性的。
Property Injection,另一方面,意味着依赖是可选的,因为编译器不会强制您分配一个值。在大多数情况下,依赖关系并不是真正可选的,因此应该很少使用这种模式。
关于c# - ASP.NET MVC web 项目中的单元测试类是一个很好的例子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4771647/