2

我正处于“啊哈!”的边缘。在编码领域驱动设计时。问题是如何以及在何处定义涉及实体、值对象和一些额外字段的 MVC ActionMethod 参数类? 实体和值对象类在我的存储库中定义。

我是否:

  1. 在实现其他类的存储库中创建一个自定义类(以在单个类中获取所有属性),并为额外字段添加更多属性?
  2. 在存储库中创建实体/值对象 poco 类,并在我的控制器类中创建一个引用这些对象的复合类,然后将其用作 ActionMethod 参数类型?
  3. 还有什么?

请求表单只是收集了一些客户类字段、一个邮寄地址和一些表单细节,比如他们是如何找到我们的。内容并不重要,只是它包含来自多个 pocos 的信息。

我知道 MVC 会将已发布表单的字段与 ActionMethod 参数中 Poco 的属性相匹配,如下所示:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult RequestCatalog()

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(Customer customer)

因此 customer.firstName 会自动绑定到发布表单中的 firstName。

我有以下内容:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(string fname, string lname, string address,
    string city, string state, string zip, string phone, string howTheyFoundUs)

但想要有类似的东西:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog( RequestForm requestForm)

有什么想法吗?

4

2 回答 2

2

首先,您必须意识到域模型必须独立于运行时框架 (MVC) 进行定义。想象一下,将来您必须能够将域模型公开为 WCF 服务、WPF/Silverlight 富客户端、批处理作业或其他东西......

这意味着所有建模都必须不受技术细节的限制。在设计过程的这个阶段,必须(很大程度上)忽略如何存储数据以及如何使用域对象的细节。

你必须经常问自己:这个类作为纯域的一部分有意义吗?

在您的特定情况下,您的大部分输入听起来都属于具有类似结构的 Customer 类

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }
    public Address Address { get; set; }
}

Address 类的定义类似。

现在您需要问自己(或与您一起工作的任何领域专家)的问题:是否howTheyFoundUs属于 Customer 类?或者它本身就是一个域概念?或者它真的只是一个与领域模型没有任何关系的特定于应用程序的数据?这些问题的答案将指导您最终如何对输入进行建模。

顺便说一句,上面的 Phone 属性对我来说看起来很可疑,但它是一个很好的例子,说明了实现细节(在本例中为 ASP.NET MVC)如何泄漏到模型中。

电话号码本身应该是一个值对象(有关此主题的相关处理,请参阅此博客文章),但 ASP.NET 的默认 ModelBinder 需要一个基本类型。更好的选择是实现一个自定义 ModelBinder,它可以将电话号码解析为适当的对象。

于 2009-12-07T08:34:54.807 回答
1

没有什么可以阻止您在操作方法中使用 Request.Form。

例如

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(Customer customer)
{
    var howTheyFoundUs = Request.Form["howTheyFoundUs"];

    // ...
}
于 2009-12-07T07:23:24.750 回答