gpt4 book ai didi

c# - 如果实体处于某种状态,如何强制执行约束,例如任何字段(或特定字段)不得更改?

转载 作者:行者123 更新时间:2023-11-30 15:42:57 25 4
gpt4 key购买 nike

我正在尝试在我当前的项目(c#、mvc、nhibernate、caSTLe)中使用 DDD,并且我正在考虑检查约束的最佳方法,该约束表明如果实体是任何字段(或特定字段)不得更改在某些状态下,即。已预订(state=booked)的发票不得更改金额字段。在服务层中,我得到了一些我需要映射到域对象的 DTO 对象(来自 gui 或 web 服务等)。映射完成后,我想验证我的对象 - 特别是我想检查问题中的特定约束。

目前我在想:

  • 在实体级别跟踪更改,即在每个 setter 上将字段添加到更改的字段集合并切换 NHibernate 以使用字段访问策略。如果不允许更改值,则此模式的变体将在 setter 上抛出异常
  • 在映射之前创建对象副本并比较原始值和映射值
  • 回退到 nhibernate 并从 nhibernate session 中获取此信息 - 但是该规则不会在实体级别强制执行(恕我直言,它破坏了 ddd)

你怎么看?你知道这有什么好的模式吗?还是我遗漏了什么,我需要改变我对这个约束的思考方式?

在此先感谢您的帮助。

最佳答案

DDD 中的域对象是“ self 验证”的。换句话说,客户端代码不可能破坏域规则,因为对象强制执行其内部不变量。例如:

public class Invoice {
private Money _amount;
private InvoiceState _state;

public void ChangeAmount(Money newAmount) {
if(_state == State.Booked) {
throw new InvalidOperationException(
"Unable to change amount for booked invoice.");
}
_amount = newAmount;
}

// Methods like this can be used by external code (UI) to check business
// rules upfront, to avoid InvalidOperationException.
public Boolean CanChangeAmount() {
if(_state == State.Booked) {
return false;
}
return true;
}
}

来自 DDD sample 的另一个示例:

  public HandlingEvent(final Cargo cargo,
final Date completionTime,
final Date registrationTime,
final Type type,
final Location location,
final Voyage voyage) {

...

if (type.prohibitsVoyage()) {
throw new IllegalArgumentException(
"Voyage is not allowed with event type " + type);
}

永远不要让您的 UI 框架将域对象视为哑数据容器。不幸的是,互联网上的许多示例和 C# 对 getter 和 setter 的强调都鼓励了这一点。如果您在不执行业务规则的情况下更改对象状态,您最终会得到“损坏”的对象。对于 NHibernate 尤其如此,因为它的 Session 会“记住”所有对象,并会在下次提交或刷新时愉快地将它们转储到数据库中。但这只是一个技术问题,主要原因是您需要能够仅通过查看 Invoice 类来推理 Invoice 相关的业务规则。另请注意,代码应基于 Ubiquitous Language .您应该看到诸如“发票”、“预订”、“金额”之类的词,而不是通用的“字段”、“属性”、“验证器”。

更新:empi,感谢您重申您的问题。您可能想提出一个新问题。这是我强调的引用

As I said in one of my comments - this question is a part of a bigger problem I'm having. I'm looking for a standard way to define domain logic and constraints only in the domain and then translate it to gui and other layers. I don't see any common pattern to the following very common demand: the domain states that field cannot be edited and this rule is automatically converted to gui logic that disables the field and makes it readonly. I'm looking for sample solution in mvc stack. I feel like I'm reinventing the wheel and most developers just give up and duplicate the logic in gui

我认为您正在寻找一种方法来声明域中的所有内容,然后“生成”用户界面。类似于 Naked Objects对于MVC ?我从未使用过这种方法,但我怀疑生成的 UI 能否赢得美观或可用性竞赛。在我看来,UI 中总会有一些业务逻辑的“重述”。一些域不变量过于复杂,涉及多个领域,需要存储库甚至可能需要外部服务。我不确定是否可以自动生成高质量的用户界面。我认为这样做的尝试可能会开始改变您的模型以符合 UI 基础架构。

关于c# - 如果实体处于某种状态,如何强制执行约束,例如任何字段(或特定字段)不得更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7132468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com