【问题标题】:MVC where to put validation that requires a db callMVC 在哪里放置需要 db 调用的验证
【发布时间】:2011-02-19 11:49:14
【问题描述】:

在 mvc 应用中采用这个简单、常见的场景:

当用户注册时,用户名必须是唯一的。

现在我已经阅读了很多关于项目结构、域驱动设计、验证、mvc 等的内容,并且我对我的逻辑层感到满意:域(模型、核心)、域服务、控制器和视图。我可以确保例如通过向我的属性添加验证属性,用户名少于 10 个字符。故障将通过服务层冒泡返回到控制器并返回到视图中。

但是对于这个简单的场景,我坚持调用堆栈的最佳解决方案 - 并且已经很好地测试过,因为这个验证需要调用 db 来检查所有其他用户名。

对我来说,这仍然是 User 模型的验证问题。我真的很希望能够创建一个自定义验证属性,以便在设置此属性时检查持久性以确保唯一性。

哇!直接调用数据库的域对象??我不确定这是一件坏事。我可以让城堡将 IRespositories 注入到域中,对,所以没有紧密耦合,毕竟它是定义数据接口的域。

有人对此有任何经验/意见吗?

【问题讨论】:

    标签: model-view-controller validation domain-driven-design


    【解决方案1】:

    对我来说,这仍然是 User 模型的验证问题。

    错了……肯定不是。用户不应该知道兄弟姐妹。

    如果用户是实体(它肯定不是),验证唯一性是包含聚合根的责任。

    如果它是一个聚合根,那么就没有太多选择(因为“没有任何东西”拥有一个聚合根,它们是全局的)——尽管它们不应该具有域逻辑,但我为此使用了存储库。但话又说回来 - 我不认为这种唯一性验证是 really valuable(请参阅“所有规则都不是平等的”)。

    【讨论】:

      【解决方案2】:

      最后我还是坚持自己的直觉,这种行为应该在域中处理,看来我并不孤单。

      S#arp 架构的最新版本包括一个新的类验证属性 HasUniqueDomainSignature,与 Property 属性 DomainSignature 结合使用。在 NHibernate.Vaidator 上调用 IsValid 时,Common Service Locator 用于定位当前 NHibernate 会话并引用持久性。

      Here's 讨论一下。

      【讨论】:

        【解决方案3】:

        如果您要使用 DDD 路由,也许您应该考虑使用命令来启动域更改。然后域对象不需要对它们进行验证:您可以对命令进行所有必需的验证。

        至于某些框架提供的基于属性的验证(如 asp.net mvc),我真的很讨厌。你的领域模型不应该是他们的关注点。域对象应始终处于有效状态,并自行维护其不变量。

        【讨论】:

        • 我不同意。验证应与我的属性声明一起描述。我会去,甚至更进一步并建议将其用于生成您的数据库模式,以便此定义是主定义,并且只在一个地方进行描述。我真的不喜欢在服务方法中看到验证,因为稍后有人可能会创建一个新的服务方法,它会执行类似的操作但无法添加验证。危险。
        • @BobTodd 您在这里谈论的更多是数据驱动的应用程序,而不是域驱动的。在 DDD 中,您不应该在实体上设置属性(此时它们会验证)。您应该通过公共方法操作您的实体,以确保实体始终有效。那里不需要验证属性。正如有人提到的,确保唯一性约束应该是包含 AR 的责任。
        • 其实我更多是在思考,在DAO提交DO之前,它会在DO上调用IsValid(),它通过反射这些属性来推断规则。它只是一种指定验证规则的简洁方式。我可以使用构造函数设置用户名(无论它是否有效)。控制器检查实例是否有效,如果不是,它会向用户发送消息。这是 DDD - 域中的逻辑,而不是逻辑存在于域之外的贫乏模型。 en.wikipedia.org/wiki/Anemic_Domain_Model
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-07
        • 2023-03-26
        • 1970-01-01
        • 2016-05-08
        • 2015-10-19
        • 2017-01-18
        相关资源
        最近更新 更多