【问题标题】:Validation When Using MVVM (WPF) with a DDD-Based Model将 MVVM (WPF) 与基于 DDD 的模型一起使用时的验证
【发布时间】:2010-11-30 21:50:00
【问题描述】:

一种常见的 MVVM/WPF 方法是将 UI 的控件直接数据绑定到底层模型对象。模型对象可能包含其自己的验证逻辑(可能通过 IDataErrorInfo 公开),或者可能由帮助程序类验证,检查模型对象实例是否存在错误。无论哪种情况,有时模型中都会包含无效数据,因此处于无效状态。

但是,在 DDD 世界中,模型永远不会处于无效状态。在使用 WPF 和 DDD 时,您建议如何执行验证?

谢谢,
本

【问题讨论】:

  • DDD 在哪里说直接绑定到 MVVM 中的模型??
  • 如果您直接绑定到模型,您不能只使用 ValidationRules(甚至只是 ValueConverters)来防止绑定将无效数据中继到模型吗?

标签: wpf validation mvvm domain-driven-design


【解决方案1】:

我认为 MVVM 中的视图不应该直接绑定到域模型,它实际上应该绑定到视图模型。然后视图模型可能处于“无效”状态,这可以通过 IDataErrorInfo 反映。只有稍后当用户操作(例如保存、确定、应用)将其应用于底层域模型时,域模型才强制执行有效性,您还可以通过不允许 UI 中的操作来阻止应用。

虽然我必须说我发现在某种程度上不重复验证逻辑并不总是那么容易。

【讨论】:

  • 你的最后一段提到了让我远离这种方法的缺点——验证逻辑成为特定于 VM 的事实,并且往往最终在与相同底层模型交互的每个 VM 中重复。
【解决方案2】:

我倾向于认为外观或类似层应该用作 MVVM“模型”。此外观可能处于无效状态(与 DDD 模型不同)。对于验证,它可以包含自己的逻辑,也可以使用 FluentValidation 等工具。一旦它处于有效状态,就可以调用它的“do action”函数。这会将外观中的数据传递给底层的 DDD 模型。使用这种方法,DDD 模型在任何时候都不会遇到无效数据。

通过这种方法,外观及其验证逻辑可以被多个视图/视图模型对使用,从而消除了每个视图模型进行自己的验证时存在的验证逻辑重复。

【讨论】:

    【解决方案3】:

    验证属于您的业务逻辑(域模型)。我建议查看FluentValidation for .NET。

    实际上,我很幸运让 ViewModel 设置器调用底层模型对象,并让 FluentValidation 抛出异常。如果您使用的是 WPF 文本框,则绑定将继续工作,但文本框将显示红色轮廓(假设您使用了文本框在每次击键时更新 ViewModel 的语法)。只是不要在 getter 中抛出异常,否则会破坏绑定。

    最好通过某种中介将所有通信从 ViewModel 路由到 Model(我介绍了 Presenter,但这可以像将 Model 操作作为 lambda 传递给某个中介的回调一样简单)。当在模型上操作时发生异常时,Presenter 会捕获异常并向用户显示一条友好的消息,其中包含异常的详细信息。为此,FluentValidation 会生成非常好的默认错误消息。

    【讨论】:

    • 我刚刚尝试绑定到一个属性并在设置器中抛出异常。它不会显示为验证失败。您是否使用某些库来执行此操作?
    • @Andy Lowry:在绑定中,您必须将 ExceptionValidationRule 添加到 Binding.ValidationRules。我似乎不必指定这些,但值得注意的是,我正在使用 UpdateSourceTrigger=Explicit 并在 BindingExpression 上调用 UpdateSource()。
    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 2013-07-03
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多