I'm struggling to decide the "correct" way to handle model-level events in the MVP pattern when serializing/deserializing.
For example, suppose I had a PropertyChanged event handler in my serializable base model class :
[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));
}
}
Child classes may or may not use event handler
[Serializable]
public class MyModel
{
public MyModel()
{
PropertyChanged += MyModel_PropertyChanged;
}
}
And non-serializable Presenters/ViewModels may also use this event handler
public class MyPresenter
{
public MyPresenter(MyModel m)
{
m.PropertyChanged += MyPresenter_PropertyChanged;
}
}
My problem is when I try to Clone the model object using serialization, I get an exception because MyPresenter
is not marked as serializable.
This could be easily fixed by adding the [NonSerialized]
attribute to the PropertyChanged
event, however then when objects get deserialized they are missing the MyModel_PropertyChanged
handler as well, which is only added in the constructor.
I was considering using an [OnDeserialized]
method in the model, and attaching the model-level event handlers there as well, however the code base I am working with is extremely large and it would be a lot of work to go through every one of or model libraries and add the custom [OnDeserialized]
method to each one, so I wanted to check if there was an alternative solution first.
Is there a way of specifying which event handlers are not serialized? Or a better of solution to this problem of how to handle event handlers in serializable objects which can be used by both the object itself and non-serializable objects?
hmmm.. just a quick answer basically there's some logic attaching this event so you should objectify this logic
e.g. (pseudo code)
you can either have this logic as an object and host it in the one who is registering this (page, or controller state etc..) so in this way you serialize the parts (references) of the things that are needed for the logic to be resumed..