MVC + DDD - 模型与参数化域对象构造函数绑定

MVC + DDD - Model binding with parameterised Domain object constructors

我有一个应用程序试图在一定程度上遵循领域驱动设计。我有一个域层,里面的 classes 有参数化的构造函数。

我的 ViewModels 当然有无参数的构造函数,以允许模型绑定。但是一页给我带来了问题。

我的一个页面显示了一个汽车列表,用户可以编辑其中的详细信息,然后通过JQuery POST 将一辆汽车的数据发送到后端。 Car 是一个域对象,只有一个带参数的构造函数(我在构造函数内部进行业务逻辑检查)。

我的后台代码是这样的

[AjaxOnly]
public JsonResult Update(Car car)
{
    //...
}

当然这会失败,因为 Car 是一个域 class 并且没有无参数构造函数。

我想知道这种情况下是否有公认的最佳实践。我可以想到两个,可能是三个选项:

1) 为 Cars 域创建无参数构造函数 class。用

装饰它
[Obsolete("For model binding only")]

防止用户直接调用。然后在我的 JsonResult 方法中立即调用参数化构造函数。不幸的是,这意味着在模型中将我的私有设置器更改为 public。

2) 接受 FormCollection,提取值,并调用参数化构造函数。这类似于 1) 但不需要更改私有设置器。

3) 也许是自定义模型活页夹?我已经为 IoC 为我的 MVC 控制器执行此操作,但不知道它如何用于非控制器。

是否有处理此问题的最佳实践方法?

你的描述有点贫血领域模型的味道。您的 Update 方法让我想到了 DDD 的 CRUD 方法。这是错误的。

您的 Car 域模型应该具有每种类型的可更新命令(例如 UpdatePriceUpdateAvailability 假设您正在开发管理限界上下文)。因此,您的表示层,换句话说,您的 ASP.NET 应用程序应该具有:

[AjaxOnly]
public JsonResult UpdateColor(UpdateColorViewModel vm)
{
    Car car = repository.getById(vm.id);
    try
       car.UpdateColor(vm.color);
    catch
       // return some sort of errors

    // return some sort of ok
}

如果您没有,严格来说,贫血领域模型,那么您的问题就是您的 UI。要应用 DDD,您需要 task-based UI design。没有好的 task-based UI 你就卡住了;身体上(你的建筑),更糟糕的是,精神上;在贫血模型中,因为您的系统不知道用户在做什么。

一旦您知道,在您的 UI 层中,用户在做什么;您可以提供从 UI 到域层操作的命令,并且您永远不必 "create" 具有更新属性的现有汽车版本。只需使用执行操作所需的信息创建命令即可。

marianoc84(对他+1)给你一个简单但有效的例子。