gpt4 book ai didi

.net - 在多个服务之间共享 dbcontext 的最佳方式是什么?

转载 作者:行者123 更新时间:2023-12-03 23:23:48 24 4
gpt4 key购买 nike

首先,如果这个问题已经得到回答,我很抱歉。但我无法找到解决方案。

假设我想创建一个订单以及一些行,同时创建另一个实体。

服务层:

public class OrderService
{
private DbContext context;

public OrderService()
{
context = new DbContext();
}

public void AddOrder(Order order, List<Orderline> lines, AnotherEntity anotherEntity)
{
context.Orders.Add(order);
context.Orderlines.AddRange(lines);

var anotherService = new AnotherService();
anotherService.AddAnother(anotherEntity)

context.SaveChanges();
}
}

public class AnotherService
{
private DbContext context;

public AnotherService()
{
context = new DbContext();
}

public void AddAnother(AnotherEntity entity)
{
// Maybe some business rules here

context.SomeOtherEntities.Add(entity);

context.SaveChanges();
}
}

Controller :
var orderService = new OrderService();
orderService.Add(order, lines, anotherEntity);

第一个问题是我在两种服务中都有不同的上下文,因此有两个不同的事务。我能想到的解决方案:
  • 将来自 Controller 的 dbcontext 通过订单服务传递给下一个服务。但这会将上下文暴露给表示层。由于每个服务中的 SaveChanges() 方法,我仍然会有两个事务。我可以通过删除 AddAnother 中的 SaveChanges() 来解决这个问题,但是如果我想独立于表示层调用它怎么办?那时什么都不会被保存。
  • 使用 BeginTransaction() 将代码包装在 AddOrder 中。但是如果 AddAnother 调用第三个服务并且也使用 BeginTransaction() 会怎样?然后我会得到多个嵌套事务。

  • 我知道存储库/UOW 模式,甚至尝试实现它,但我看不出它将如何解决这个问题。

    这是我想太多了吗?

    最佳答案

    最好的方法是在您的服务和整个软件架构中使用 IoC 容器和依赖注入(inject)模式。

    // Simple example of MVC action method that uses injected context
    public IActionResult SomeAction()
    {
    var s1 = new AnotherService(this.context);
    var s2 = new OrderService(this.context);
    // call s1 and s2 business logic

    this.context.SaveChanges();
    }


    public class AnotherService
    {
    private DbContext context;

    public AnotherService(DbContext dbcontext)
    {
    context = dbcontext;
    }

    public void AddAnother(AnotherEntity entity)
    {
    // Maybe some business rules here

    context.SomeOtherEntities.Add(entity);

    }
    }

    public class OrderService
    {
    private DbContext context;

    public OrderService(DbContext dbcontext)
    {
    context = dbcontext;
    }

    public void AddOrder(Order order, List<Orderline> lines, AnotherEntity anotherEntity)
    {
    context.Orders.Add(order);
    context.Orderlines.AddRange(lines);

    var anotherService = new AnotherService(context);
    anotherService.AddAnother(anotherEntity)
    }
    }

    是的,这是一个使用注入(inject) DbContext 的简单示例,但您可以深入研究 UoW there

    UnitOfWork 在您的服务上创建具有 DbContext 共享实例的层。
    由于所有服务都依赖于 UoW 及其上下文,因此您可以提交使用 DbContext 保存数据的 UoW。例如:
    // Simple example of MVC action method that uses injected context
    public IActionResult SomeAction()
    {
    using(var uow = new UnitOfWork())
    {
    var s1 = new AnotherService(uow.Context);
    var s2 = new OrderService(uow.Context);
    // call s1 and s2 business logic
    uow.Commit(); // Commit method implements this.context.SaveChanges(); logic.
    }
    }

    在此实现中,您的所有服务都将具有相同的 DbContext 实例。

    关于.net - 在多个服务之间共享 dbcontext 的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33463477/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com