如何处理 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(..?.);
}
}
问题:
服务无法知道
InitialSetupViewModel
,那么应该传递给服务什么?服务必须了解
BusinessDbContext
和RolesDbContext
。所以我必须在两者上调用 SaveChanges((,这超过了拥有单个 IUnitOfWork 的目的。我是否必须创建另一个同时包含业务实体和角色实体的工作单元?
我认为将这两个 IUnitOfWorks 合并为一个只是为了让这个 MVC 视图工作是不合理的。但解决方案是什么?
谢谢!
一个你不知道的领域有强烈的看法总是很困难的,但它是这样的:
正如已经评论的那样,
Controller
应该负责视图和域模型、DTO 或其他模型之间的映射。它可以将InitialSetupViewModel
实例作为输入,但实现细节可能会有所不同。
的确,如果您发现自己需要以其他方式打破边界上下文的边界,那么重塑域可能是正确的选择。不过,只关注工作单元模式,我不太明白你的犹豫。
工作单元实现负责跟踪在一个事务中需要同步的所有域对象。同一个域对象涉及几个不同的工作单元,这并不奇怪。这并不意味着在处理其他类型的聚合时,您应该将"较小"的工作单元实现组合成"较大"的实现,但当然,在一个工作单元中同时包含"角色"和"业务"。
这样做不应该被你的视图的外观所吸引,而应该被你的领域模型中的"真实"所吸引,而不是仅仅处理域对象的集合,你的域应该描述合适的聚合。
也许甚至可以使用单独的事务(工作单元(存储每个域对象,即如果不需要同步它们 - 例如,如果(甚至可能希望(未能持久化Business
不会阻止Roles
通过,反之亦然。实际上,我认为人们甚至可以争辩说,如果边界上下文实际上被正确定义,那么情况应该是这样。
我希望这些评论有所帮助。
Martin Fowler谈工作单元和聚合。