1

After further pondering the implications of DataContractSerializer not calling constructors or static field initializers, it seems like a cleaner design pattern to have properties self-initialize like this:

private ObservableCollection<object> myObjects;
public ObservableCollection<object> MyObjects
{
    get 
    { 
        if (myObjects == null) myObjects = new ObservableCollection<object>();
        return myObjects; 
    }
    set
    {
        myObjects = value;
    }
}

as opposed to providing two initialization paths like this:

public MyClass()
{
    InitializeClass();
}

[OnDeserialized()]
private void OnDeserialized(StreamingContext c)
{
    InitializeClass();
}

private void InitializeClass()
{
    // Note here I can still use a field.  
    // Self-initialization requires a property.
    myObjects = new ObservableCollection<objects>();
}   

My main concern is that the latter pattern will not fail unit tests that construct the class with new should the special OnDeserialized initialization be forgotten, unless those unit tests are specifically designed to have knowledge that they may be used with DataContractSerializer at some point.

That feels too entangled.

One downside of the self-initialization approach is that it requires properties rather than fields (since field initializers are ignored by DataContractSerializer).

Are there other downsides that I am not considering?

Community
  • 1
  • 1
Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • I guess one question is: what use cases do you have that require properties in the data contracts that aren't serialized? – Joe Feb 28 '12 at 22:49
  • Joe: This question from a real-life case where the internal state of the object had to be constructed from serialized data. Storing the internal state would be redundant. The example is highly simplified to highlight the core issue that DataContractSerializer bypasses standard object initialization (constructors and field initializers) and try to arrive at the best design pattern to deal with that fact. – Eric J. Feb 28 '12 at 22:57
  • I'm very familiar with that behavior, we got bitten by it once or twice. But the vast majority of our data contracts did not require this complex calculated state. My point is: if you have any kind of real logic inside your data contract classes, perhaps that logic doesn't belong there. Alternately, you could store a simple flag field that indicates whether the object was constructed via a constructor or not (just set a non-serialized bool in the constructor) and then use the flag on access to the non-serialized properties... – Joe Feb 28 '12 at 23:32
  • @Joe: We strive to have business objects that are ignorant of persistence (yay EF Code First) and serialization (boo DataContractSerializer) issues. – Eric J. Feb 29 '12 at 01:12

1 Answers1

0

This is a stretch, but it might work for you, depending on how much of this magic calculatable data you have, and to what extent you use it. You can use IObjectReference to deal with it. See http://blogs.msdn.com/b/carlosfigueira/archive/2011/09/27/wcf-extensibility-other-serialization-extensions.aspx for an example.

krisragh MSFT
  • 1,908
  • 1
  • 13
  • 22