Ale*_*lex 13 c# asp.net asp.net-mvc repository-pattern
我设计了一个使用存储库模式的应用程序,然后设计了一个单独的服务层,例如:
public class RegistrationService: IRegistrationService
{
public void Register(User user)
{
IRepository<User> userRepository = new UserRepository();
// add user, etc
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我在Register方法中实例化我的存储库.现在,因为我想编写一些单元测试,我真的无法实现它并用虚假的存储库替换它可以吗?
我不想将存储库添加为类变量(并通过构造函数设置),因为我认为这会使我的代码"臭"(并非所有方法都需要所有存储库,而且我不需要调用层来了解存储库等).
建议?
jri*_*sta 16
您需要使用依赖注入.UserRepository是RegistrationService类的依赖项.为了使您的类适当地单元可测试(即隔离它们的依赖项),您需要"反转"控制依赖项创建的内容.目前,您可以直接控制,并在内部创建它们.只需反转该控件,并允许外部的东西(如像Castle Windsor这样的IoC容器)注入它们:
public class RegistrationService: IRegistrationService
{
public RegistrationService(IRepository<User> userRepo)
{
m_userRepo = userRepo;
}
private IRepository<User> m_userRepo;
public void Register(User user)
{
// add user, etc with m_userRepo
}
}
Run Code Online (Sandbox Code Playgroud)
我想我忘了添加.一旦允许注入依赖项,就可以打开它们可模拟的可能性.由于您的RegistrationService现在将其依赖用户存储库作为其构造函数的输入,因此您可以创建模拟存储库并将其传递,而不是实际存储库.
依赖注入对于这些事情来说非常方便:
public class RegistrationService: IRegistrationService
{
public void Register(User user)
{
this(user, new UserRepository());
}
public void Register(User user, IRepository<User> userRepository)
{
// add user, etc
}
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以使用UserRepository作为默认设置,并为您需要的任何其他内容传递自定义(Mock或Stub进行测试)IRepository.您可能还想更改第二个寄存器方法的范围,以防您不想将其暴露给所有内容.
一个更好的选择是使用一个IoC容器,它会为你购买比上面例子更加分离的语法.你可以得到这样的东西:
public class RegistrationService: IRegistrationService
{
public void Register(User user)
{
this(user, IoC.Resolve<IRepository<User>>());
}
public void Register(User user, IRepository<User> userRepository)
{
// add user, etc
}
}
Run Code Online (Sandbox Code Playgroud)
有许多IoC容器,如其他人的答案所列,或者你可以自己推出.
| 归档时间: |
|
| 查看次数: |
3401 次 |
| 最近记录: |