一个简单的C#POCO撤消/重做系统

时间:2014-01-20 07:56:48

标签: c# poco history undo-redo

我在内存中使用POCO(类对象)来处理每种类型的数据。我有一组myraid函数可以对它们进行操作并以不同的方式对它们进行修改。使用最少的代码更改来实现撤消/重做功能的简单方法是什么?一些想法:

  • 使用ORM记录更改 - Property-level logging - 修改POCO的方法应记录他们修改的每个属性,或通过ORM修改属性而不是直接操作波苏斯。 ORM会记录更改并在需要时恢复。

  • 深度克隆和差异 - Memento pattern - 在修改对象之前保存对象的深层克隆(浪费内存,慢)。完成修改后,调用一个计算对象属性差异的函数(必须遍历所有道具,缓慢,乏味,递归)。差异存储在日志中以便以后可以还原。

  • 每个命令都支持撤消/重做 - Command pattern - 经典方法,但它需要添加太多代码。我正在寻找通用的东西,理想情况下不需要从头开始重写应用程序。

我不知道这种问题的典型方法,但考虑到它相当普遍,我确信有很好的模式来解决这个问题而不会有太多麻烦。您是否知道以简单方式处理POCO历史的任何模式/库?

我目前正在审核以下内容,但仍在寻找更好的方法。

1 个答案:

答案 0 :(得分:2)

可能的高级方法:

  1. 使用virtual
  2. 标记您的POCO属性
  3. 将对象实例化请求重定向到所述类的自定义工厂(如果您已经使用依赖项注入,这很容易)
  4. 您的自定义工厂第一次收到某个目标类的实例化请求时,使用反射来发出一个覆盖目标属性的新类(可能使用自定义[UndoRedo]属性修饰?)
  5. 重写的set{}实现将识别更改,并创建一个更改标识对象(仅标识属性,对象引用和旧值),该对象将被推送到您的更改堆栈。然后调用基类的set方法。可能需要在IL中编写一些代码。
  6. 要撤消更改,请将更改标识符从堆栈中弹出,并使用首选方法将旧值应用于给定对象引用上的给定属性
  7. 结果是支持的类的使用者不会注意到任何差异(除了对象创建,请参阅步骤2)。