为可序列化模型对象编写事件处理程序的正确方法是什么?

时间:2015-06-09 15:46:42

标签: c# events serialization .net-3.5

我正在努力决定"正确"在序列化/反序列化时处理MVP模式中的模型级事件的方法。

例如,假设我的可序列化基本模型类中有一个PropertyChanged事件处理程序:

[Serializable]
public abstract class MyBaseModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

子类可能使用也可能不使用事件处理程序

[Serializable]
public class MyModel
{
    public MyModel()
    {
        PropertyChanged += MyModel_PropertyChanged;
    }
}

非序列化的Presenters / ViewModel也可以使用此事件处理程序

public class MyPresenter
{
    public MyPresenter(MyModel m)
    {
        m.PropertyChanged += MyPresenter_PropertyChanged;
    }
}

我的问题是当我尝试使用序列化克隆模型对象时,我得到一个例外,因为MyPresenter未标记为可序列化。

可以通过向[NonSerialized]事件添加PropertyChanged属性来轻松修复此问题,但是当对象进行反序列化时,它们也会丢失MyModel_PropertyChanged处理程序,这只会添加到构造函数。

我正在考虑在模型中使用[OnDeserialized]方法,并在那里附加模型级事件处理程序,但是我正在处理的代码库非常大,这将是很多工作浏览每一个或模型库,并为每个库添加自定义[OnDeserialized]方法,因此我想先检查是否有替代解决方案。

有没有办法指定哪些事件处理程序没有序列化?或者更好地解决如何在可序列化对象中处理事件处理程序的问题,这些对象本身和非可序列化对象都可以使用它?

1 个答案:

答案 0 :(得分:0)

嗯......嗯,快点回答 基本上有一些逻辑附加这个事件 所以你应该客观化这个逻辑

e.g。 (伪代码)

class MyHandlingLogic : IDisposable
 Target { get; set; }
 RegistrationDelegate { get; set; }
 OnTargetSet(target) { 
   this.RegistrationDelegate = ...; // some code utilizing all properties set
   target.TargetEvent += this.RegistrationDelegate; 
 }
 Dispose() { target.TargetEvent -= this.RegistrationDelegate; }
}

你可以将这个逻辑作为一个对象,并将它托管在注册它的那个(页面或控制器状态等)中。这样你就可以序列化所需内容的部分(引用)。要恢复的逻辑..