1

我们正在编写一个MVC数据维护应用程序,它是大型项目的一部分。我们尝试使用域驱动设计DDD。 关于此问题,已有其他问题,如here,herehere。 但他们并没有完全回答我的问题。如何处理MVC ViewModel - 域模型 - MVC控制器和服务中的实体

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

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

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

视图模型是这两个和其他领域模型的扁平化,简化模型:

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

这个视图模型应该映射到域模型,我们正在与Automapper做。

控制器获得注入的域名服务:

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的目的。 我是否还需要创建另一个包含业务和角色实体的UnitOfWork?

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

谢谢!

+2

您在控制器上的'Create'动作方法会接受您的视图模型,然后您将转换为DTO并将其传递给您的服务 – 2014-12-01 21:22:41

+0

对于我来说,单个应用事务跨越多个有界上下文的事实表明设计异味。聚合之间有多种方式进行事后沟通,可能属于不同的BC,但交易应尽可能多地修改一个聚合。 – guillaume31 2014-12-02 10:35:59

回答

1

它总是很难有你不知道的域强烈的意见,但这里有云:

  1. 如已经评论说,在Controller应承担观点和域之间的映射责任模型,DTO或你有什么。可能需要输入InitialSetupViewModel的实例,但实现细节可能会有所不同。

  2. 如果您发现自己需要打破有界上下文的边界,那么重塑域可能是是正确的选择。尽管只关注工作单元模式,但我并不十分犹豫。

    单位工作实施的责任是跟踪全部需要在一个事务中同步的域对象。在几个不同的工作单元中涉及相同的域对象并没有什么奇怪的。这并不意味着当你处理另一种聚合时,你应该将“较小”的工作单元实现合并为“较大”的实现,但在一个工作单元中同时包括“角色”和“业务”。

    这样做应该而不是被你的视图看起来像什么,但是由你的域模型中的“真实”引诱,而不是仅仅处理域对象的集合,你的域可能应该描述合适的聚集体。

也许它甚至OK保存有独立的交易每个域对象(工作单位),即如果他们同步是没有必要的 - 例如,如果(或者甚至是期望的)没有坚持下去,Business不会阻止Roles通过,反之亦然。实际上,我认为人们甚至可以争辩说,如果有界的上下文实际上是正确定义的,那么应该是

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

Martin Fowler on Unit of Work and Aggregates

相关问题