为什么不将所有服务类转换为Factory方法(而不是注入接口)?

And*_*rew 11 c# structuremap unit-testing dependency-injection

我们正在构建一个ASP.NET项目,并将所有业务逻辑封装在服务类中.有些是在域对象中,但通常那些是相当贫血的(由于我们正在使用的ORM,这不会改变).为了更好地启用单元测试,我们为每个服务定义接口并使用DI.例如,这里有几个接口:

IEmployeeService
IDepartmentService
IOrderService
...
Run Code Online (Sandbox Code Playgroud)

这些服务中的所有方法基本上都是任务组,并且这些类不包含私有成员变量(除了对依赖服务的引用).在我们担心单元测试之前,我们只是将所有这些类声明为静态并让它们直接相互调用.现在,如果服务依赖于其他服务,我们将设置这样的类:

public EmployeeService : IEmployeeService
{
   private readonly IOrderService _orderSvc;
   private readonly IDepartmentService _deptSvc;
   private readonly IEmployeeRepository _empRep;

   public EmployeeService(IOrderService orderSvc
                        , IDepartmentService deptSvc
                        , IEmployeeRepository empRep)
   {
      _orderSvc = orderSvc;
      _deptSvc = deptSvc;
      _empRep = empRep;
   }
   //methods down here
}
Run Code Online (Sandbox Code Playgroud)

这通常不是一个问题,但我想知道为什么不建立一个我们传递的工厂类呢?

public ServiceFactory
{
   virtual IEmployeeService GetEmployeeService();
   virtual IDepartmentService GetDepartmentService();
   virtual IOrderService GetOrderService();
}
Run Code Online (Sandbox Code Playgroud)

然后而不是调用:

_orderSvc.CalcOrderTotal(orderId) 
Run Code Online (Sandbox Code Playgroud)

我们打电话

_svcFactory.GetOrderService.CalcOrderTotal(orderid)
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点是什么?它仍然是可测试的,它仍然允许我们使用DI(并通过工厂内外的DI处理外部依赖关系,如数据库上下文和电子邮件发件人),它消除了大量的DI设置并更多地整合了依赖关系.

谢谢你的想法!

小智 2

如果您的大多数类依赖于这三个接口,您可以传递一个将它们包装在一起的对象,但是:如果大多数类仅依赖于其中的一两个接口,那么这不是一个好主意,因为这些类将有权访问对象他们不需要,也没有关系,一些程序员总是会调用他们不应该调用的代码,只是因为它可用。

顺便说一句,它不是一个工厂,除非您总是在 Get[...]Service() 方法中创建一个新对象,并且仅仅为了传递一些方法而这样做是不好的。我只是将其称为 ServiceWrapper 并将它们转换为属性 EmployeeService、DepartmentService 和 OrderService。