【发布时间】:2012-08-02 12:13:21
【问题描述】:
我正在使用 C#、MVC4、StructureMap 等开发 Web 解决方案。
在解决方案中,我为控制器提供服务。举例:
public class ServiceA{
private readonly IRepository _repository1;
private readonly IRepository _repository2;
public ServiceA(IRepository1 repository1, IRepository2 repository2){
_repository1=repository1;
_repository2=repository2;
}
public void DoSomethingA(){
_repository1.DoSomething();
}
public void DoSomethingB(){
_repository2.DoSomething();
}
}
public class ServiceB{
private readonly IRepository _repository3;
private readonly IRepository _repository4;
public ServiceB(IRepository3 repository3, IRepository4 repository4){
_repository3=repository3;
_repository4=repository4;
}
public void DoSomethingA(){
_repository3.DoSomething();
}
public void DoSomethingB(){
_repository4.DoSomething();
}
}
这样做是个好习惯吗? :
public abstract class ServiceBase(){
public IRepository1 Repository1 { get { return instanceOf<IRepository1>(); }}
public IRepository2 Repository2 { get { return instanceOf<IRepository2>(); }}
public IRepository3 Repository3 { get { return instanceOf<IRepository3>(); }}
public IRepository4 Repository4 { get { return instanceOf<IRepository4>(); }}
private T instanceOf<T>()
{
return ServiceLocator.Current.GetInstance<T>();
}
}
然后以这种方式创建服务?
public class ServiceA : ServiceBase
{
public void DoSomethingA(){
Repository1.DoSomething();
}
public void DoSomethingB(){
Repository2.DoSomething();
}
}
public class ServiceB : ServiceBase
{
public void DoSomethingA(){
Repository3.DoSomething();
}
public void DoSomethingB(){
Repository4.DoSomething();
}
}
使用第二个选项,我看到了某些优势:
- 不必为每个存储库都有一个私有变量。
- 我不需要服务的构造函数,使它们更小更易于阅读。
- 所有存储库都可以在任何服务中使用。
- 服务没有获得不必要的实例。例如,在
ServiceA方法DoSomethingA中调用ServiceLocator只得到Repository1实例。 (使用第一种方法会收到两个实例:Repository1和Repository2)
在这两种情况下,我都可以进行适当的测试:
- 在第一种情况下,通过构造函数发送模拟对象。
- 在第二种情况下,将 StructureMap 配置为在必要时使用模拟对象。
你觉得呢?我违背了一些原则? (对不起我的英语)
【问题讨论】:
标签: c# asp.net-mvc dependency-injection structuremap recommendation-engine