C# 在服务中使用UnitOfWork的哪种变体更合适?
你好 我的系统具有N层体系结构:C# 在服务中使用UnitOfWork的哪种变体更合适?,c#,asp.net-mvc-4,architecture,C#,Asp.net Mvc 4,Architecture,你好 我的系统具有N层体系结构: DAL(数据访问层)(实体框架6,存储库, (工作单位) BLL(业务逻辑层) PL(表示层)(ASP.NET MVC 4) 问题如下: 使用哪个UnitOfWork变体更合适? 第一个变量(特性的使用,在控制器ASP.NET MVC中显式调用Dispose()): 换句话说-从一个服务方法调用第二个服务是否正确? 提前谢谢 我认为私有变量unitofwork是一种更好的方法,因为它更倾向于控制反转,但控制并没有被注入,而且对我来说,使用块方法不应该在它们自
- DAL(数据访问层)(实体框架6,存储库, (工作单位)
- BLL(业务逻辑层)
- PL(表示层)(ASP.NET MVC 4)
提前谢谢 我认为私有变量unitofwork是一种更好的方法,因为它更倾向于控制反转,但控制并没有被注入,而且对我来说,使用块方法不应该在它们自己的服务中完成。 应该注入unitofwork对象,并在其他位置进行控制。在我看来,unitofwork模式的全部要点是封装事务范围。此事务作用域应该能够跨越服务。良好的封装原则指导我们创建原子服务,这些服务是单焦点的(固态的)。i、 在你的情况下,所有与信息有关的事情都应该在信息服务中,这是正确的。但正如您所看到的,由于这一原则,其他服务可能需要发送消息。因此,是的,我认为一个服务调用另一个服务并不是不合理的,特别是当需要强制执行业务规则时。事实上,多个服务进入同一个存储库,可能做同样的事情。 我还认为,如果消息发送失败,最好不要发送消息,或者回滚第一个操作(不管是什么操作)。当然,您可以对此进行测试(if..then..type模式),并可能手动编写回滚代码(丑陋!),但将您使用的所有服务包装到同一个unitofwork意味着您无论如何都有一种回滚(和提交)类型的方法(特别是如果您使用的是ORM映射器,即实体框架),很多内嵌的if语句可能有点代码味道 因此,您没有将unitofwork注入到服务中,因此您的事务范围仅限于在其中创建它的服务。这也使得测试更加困难。所有这些问题都与我目前在另一个项目中所经历的完全相同,该项目遵循相同的代码结构/方法,我将首先说,我还没有找到一个完美的方法,但我将更像这样处理:
//Base service class to take the unit of work injection
public abstract class BaseService
{
private IUnitOfWork _uow { get; private set; }
public BaseService(IUnitOfWork scope)
{
_uow = scope;
}
}
然后是服务类实现
public class SomeService: BaseService, ISomeService
{
public MyService(IUnitOfWork scope) : base(scope)
{
}
public void SomeMethod(int somevalue)
{
//Do something in this service
//code here.....
//then do something in the next service, passing though
//the same unitof work
messageService = new MessageService(_uow );
messageService.Send(1, 2, "some text");
}
}
这将控制unitofwork(范围)的职责传递给调用方。在您的例子中,是PL表示层,或者为了方便测试另一个测试类(如果您愿意)。从PL来看,类似于:
//PL Controller that does something cool
public class BaseService : Controller
{
public ActionResult DoSomething(int value)
{
using(IUnitOfWork scope = new UnitOfWork())
{
ISomeService theService = new SomeService(scope);
theService.SomeMethod(value);
}
...con
}
}
实际上,我在PL和BLL之间放置了另一层来控制作用域,依赖性注入服务,如果您愿意的话,有点像unitofworkcontroller
无论如何,我认为我的2美分私有变量unitofwork是一个更好的方法,因为它更倾向于控制反转,但控制没有注入,而且我的使用块方法不应该在服务中完成。 应该注入unitofwork对象,并在其他位置进行控制。在我看来,unitofwork模式的全部要点是封装事务范围。此事务作用域应该能够跨越服务。良好的封装原则指导我们创建原子服务,这些服务是单焦点的(固态的)。i、 在你的情况下,所有与信息有关的事情都应该在信息服务中,这是正确的。但正如您所看到的,由于这一原则,其他服务可能需要发送消息。因此,是的,我认为一个服务调用另一个服务并不是不合理的,特别是当需要强制执行业务规则时。事实上,多个服务进入同一个存储库,可能做同样的事情。 我还认为,如果消息发送失败,最好不要发送消息,或者回滚第一个操作(不管是什么操作)。当然,您可以对此进行测试(if..then..type模式),并可能手动编写回滚代码(丑陋!),但将您使用的所有服务包装到同一个unitofwork意味着您无论如何都有一种回滚(和提交)类型的方法(特别是如果您使用的是ORM映射器,即实体框架),很多内嵌的if语句可能有点代码味道 因此,您没有将unitofwork注入到服务中,因此您的事务范围仅限于在其中创建它的服务。这也使得测试更加困难。所有这些问题都与我目前在另一个项目中所经历的完全相同,该项目遵循相同的代码结构/方法,我将首先说,我还没有找到一个完美的方法,但我将更像这样处理:
//Base service class to take the unit of work injection
public abstract class BaseService
{
private IUnitOfWork _uow { get; private set; }
public BaseService(IUnitOfWork scope)
{
_uow = scope;
}
}
然后是服务类实现
public class SomeService: BaseService, ISomeService
{
public MyService(IUnitOfWork scope) : base(scope)
{
}
public void SomeMethod(int somevalue)
{
//Do something in this service
//code here.....
//then do something in the next service, passing though
//the same unitof work
messageService = new MessageService(_uow );
messageService.Send(1, 2, "some text");
}
}
这将控制unitofwork(范围)的职责传递给调用方。在您的例子中,是PL表示层,或者为了方便测试另一个测试类(如果您愿意)。从PL来看,类似于:
//PL Controller that does something cool
public class BaseService : Controller
{
public ActionResult DoSomething(int value)
{
using(IUnitOfWork scope = new UnitOfWork())
{
ISomeService theService = new SomeService(scope);
theService.SomeMethod(value);
}
...con
}
}
实际上,我在PL和BLL之间放置了另一层来控制作用域,依赖性注入服务,如果您愿意的话,有点像unitofworkcontroller
不管怎样,我的两分钱你为什么new()
upUnitOfWork
和SomeService
?如果我们谈论的是DI,那么您将把它们的接口注入到BaseService
构造函数中。@OJay谢谢!你说:我实际上在PL和BLL之间放了另一层来控制作用域,依赖注入服务,如果你愿意的话,有点像unitofworkcontroller。你能给我看看这个图层的例子吗?而且PL
不应该引用DAL
(这里的UnitOfWork),对不对?为什么你