Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在服务中使用UnitOfWork的哪种变体更合适?_C#_Asp.net Mvc 4_Architecture - Fatal编程技术网

C# 在服务中使用UnitOfWork的哪种变体更合适?

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是一种更好的方法,因为它更倾向于控制反转,但控制并没有被注入,而且对我来说,使用块方法不应该在它们自

你好

我的系统具有N层体系结构:

  • DAL(数据访问层)(实体框架6,存储库, (工作单位)
  • BLL(业务逻辑层)
  • PL(表示层)(ASP.NET MVC 4)
问题如下:

使用哪个UnitOfWork变体更合适?

第一个变量(特性的使用,在控制器ASP.NET MVC中显式调用Dispose()):

换句话说-从一个服务方法调用第二个服务是否正确?


提前谢谢

我认为私有变量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()
up
UnitOfWork
SomeService
?如果我们谈论的是DI,那么您将把它们的接口注入到
BaseService
构造函数中。@OJay谢谢!你说:我实际上在PL和BLL之间放了另一层来控制作用域,依赖注入服务,如果你愿意的话,有点像unitofworkcontroller。你能给我看看这个图层的例子吗?而且
PL
不应该引用
DAL
(这里的UnitOfWork),对不对?为什么你