我有一个应用程序,试图遵循领域驱动设计在一定程度上。我有一个域层,里面的类有参数化的构造函数。
我的ViewModels当然有无参数的构造函数,以允许模型绑定。但是有一页给我出了问题。我的一个页面显示了一个汽车列表,用户可以编辑其中的详细信息,然后通过JQuery POST将一辆汽车的数据发送到后端。Car是一个Domain对象,并且只有一个带参数的构造函数(我在构造函数中进行业务逻辑检查)。
我的后端代码看起来像这样
[AjaxOnly]
public JsonResult Update(Car car)
{
//...
}
这当然会失败,因为Car是一个Domain类,没有无参数构造函数。
我想知道对于这种情况是否有公认的最佳实践。我能想到两三个选项
1)为Cars域类创建一个无参数构造函数。用
装饰[Obsolete("For model binding only")]
以防止用户直接调用它。然后在我的JsonResult方法中立即调用参数化构造函数。不幸的是,这意味着在模型中将我的private setter更改为public。
2)接受一个FormCollection,提取值,并调用参数化构造函数。这与1)类似,但不需要更改私有设置。
3)也许是一个定制的模型绑定器?我已经为我的MVC控制器做了IoC,但不知道它对非控制器如何工作。
是否有最佳实践方法来处理这个问题?
你的描述闻起来像贫血的领域模型。您的Update
方法让我想到了DDD的CRUD方法。这是错误的。
您的Car
域模型应该具有每种类型的可更新命令(例如UpdatePrice
, UpdateAvailability
假设您正在开发受管理约束的上下文)。这是表示层,也就是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,你需要基于任务的UI设计。如果没有基于任务的UI,你就会陷入困境;身体上(你的架构),更糟糕的是精神上;在贫血模型中,因为你的系统不知道用户在做什么
一旦你知道,在你的UI层,用户在做什么;你可以从UI向域层动作提供命令,而不必"创建"一个带有更新属性的现有汽车版本。只需创建包含执行操作所需信息的命令。
marianoc84 (+1 to him)给了你一个简单但有效的例子。