如何处理 MVC 视图模型 - 域模型 - MVC 控制器和服务中的实体

本文关键字:MVC 模型 控制器 服务 实体 何处理 处理 视图 | 更新日期: 2023-09-27 18:32:38

我们正在编写一个MVC数据维护应用程序,这是一个更大项目的一部分。我们尝试使用域驱动的设计 DDD。SO上已经有其他关于这个问题的问题,比如这里,这里和这里。然而,他们并没有完全回答我的问题。

我们在数据层中也有边界上下文,因为数据库有 755 个表。因此,我们为业务、角色、产品、客户等创建了边界上下文。

我们遇到的问题是,在 MVC 应用程序中,我们有一个用于"初始设置"的视图,该视图使用 ViewModel,该视图模型最终跨越多个边界上下文(在实体框架 6 中使用 IUnitOfWork 模式(。因此,该视图必须写入业务上下文和角色上下文。

域模型将具有一个Business模型和一个Address模型,以及更大的pbject图中的其他一些模型。

ViewModel 是这两个模型和其他域模型的扁平简化模型:

public class InitialSetupViewModel
{
    string BusinessName{get;set;}
    string Street{get;set;}
    string Street2{get;set;}
    string State{get;set;}
    string ZIP{get;set;}
    ...
}

此视图模型应映射到域模型,我们正在使用自动映射器执行此操作。

控制器获取注入的域服务:

public class SetupController : Controller
{
    private readonly IMaintenanceService service;
    public SetupController( IMaintenanceService maintenanceService = null )
     {
        service = maintenanceService;
    }
    public void Create(...????....)
    {
        service.CreateBusiness(..?.);
    }
}

问题:

  1. 服务无法知道InitialSetupViewModel,那么应该传递给服务什么?

  2. 服务必须了解BusinessDbContextRolesDbContext。所以我必须在两者上调用 SaveChanges((,这超过了拥有单个 IUnitOfWork 的目的。我是否必须创建另一个同时包含业务实体和角色实体的工作单元?

我认为将这两个 IUnitOfWorks 合并为一个只是为了让这个 MVC 视图工作是不合理的。但解决方案是什么?

谢谢!

如何处理 MVC 视图模型 - 域模型 - MVC 控制器和服务中的实体

一个你不知道的领域有强烈的看法总是很困难的,但它是这样的:

  1. 正如已经评论的那样,Controller应该负责视图和域模型、DTO 或其他模型之间的映射。它可以将InitialSetupViewModel实例作为输入,但实现细节可能会有所不同。

  2. 的确,如果您
  3. 发现自己需要以其他方式打破边界上下文的边界,那么重塑域可能是正确的选择。不过,只关注工作单元模式,我不太明白你的犹豫。

    工作单元实现负责跟踪在一个事务中需要同步的所有域对象。同一个域对象涉及几个不同的工作单元,这并不奇怪。这并不意味着在处理其他类型的聚合时,您应该将"较小"的工作单元实现组合成"较大"的实现,但当然,在一个工作单元中同时包含"角色"和"业务"。

    这样做不应该被你的视图的外观所吸引,而应该被你的领域模型中的"真实"所吸引,而不是仅仅处理域对象的集合,你的域应该描述合适的聚合。

也许甚至可以使用单独的事务(工作单元(存储每个域对象,即如果不需要同步它们 - 例如,如果(甚至可能希望(未能持久化Business不会阻止Roles通过,反之亦然。实际上,我认为人们甚至可以争辩说,如果边界上下文实际上被正确定义,那么情况应该是这样。

我希望这些评论有所帮助。

Martin Fowler谈工作单元和聚合。