在使用时对域对象进行更改

时间:2012-11-23 08:14:26

标签: c# .net mvvm domain-driven-design concurrentmodification

我们有一组域对象,可以在一个窗口中进行编辑,并在其他窗口中同时使用。确保对象始终处于有效状态,并且在提交之前外部世界不会看到更改。对象存储在存储库中(每个对象都有唯一的ID)。

  1. 用户打开“运行” - 窗口(对象A的只读访问)
  2. 用户打开“编辑”窗口(对象A的读/写访问权限)
  3. 用户更改了UI中的某些属性,但未单击“应用”
  4. 用户单击“运行”窗口中的“运行”按钮。应使用“旧”设置执行运行操作。
  5. 用户单击“编辑”窗口中的“应用”按钮,然后单击“运行”窗口中的“运行”。使用“新”设置执行运行操作。
  6. 我可以想到一些解决方案,但我对其中任何一个都不满意:

    1. 从存储库中签出对象时,始终会返回克隆。如果希望存储更改,则必须将对象显式提交到存储库。这可以很好地适用于小对象,但是在对象模型很大的情况下,克隆所有内容可能并不合理。
    2. 视图模型或模型存储中间更改,并且在用户决定应该应用更改之前不会更改基础域对象。这听起来有点单调乏味,在视图模型中需要很多验证规则,我们宁愿在域对象中使用这些规则。
    3. UI不直接对域对象起作用。相反,它们会更改可在用户应用更改时应用于域对象的DTO。
    4. 请注意,只有一个并发编辑器,但可能有多个并发“读者”。此外,并发性不会成为问题(在多线程环境中,部分更新的对象)。

      在提交更改之前,我们如何实现用于编辑域对象的模式而不应用更改?有没有我应该研究的框架?

1 个答案:

答案 0 :(得分:3)

我认为Command pattern可以帮助你。{ 您基本上将实现“编辑”窗口以不直接处理对象,而是创建根据UI中的数据更改对象的命令。单击“应用”后,您可以在对象上执行这些命令,使其进入用户选择的状态。

另一种方法是给Edit和Run窗口各自提供自己的实例,并在用户单击Apply后“以某种方式”同步“运行”窗口中的对象。但是,我不太确定如何在不引入大量耦合的情况下实现这一点。

第三种方法是我要实施的方法:
在使用MVVM时,编辑窗口和运行窗口都有自己的 ViewModel 实例。 ViewModel可以包含域对象的实例。两个ViewModel都会将一个实例保存到域对象的相同实例中 现在,ViewModel可以通过以下方式实现:

  1. 如果不存在更改(见下文),则其属性getter将返回基础域对象的值。
  2. 当调用ViewModel上的属性设置器时,该值不会写入域对象,而是写入ViewModel中的相应字段。那是一个变化。从现在开始,ViewModel将返回该值。
  3. ViewModel有一个将更改写入域对象的方法。此方法不会自动调用,当用户在“编辑”窗口中单击“应用”时,将调用此方法。
  4. “运行”窗口中的ViewModel将始终从基础域对象返回数据,因为它永远不会发生更改。