<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>emphess .NET &#187; Reflection</title>
	<atom:link href="http://www.emphess.net/tag/reflection/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.emphess.net</link>
	<description>Christoph Menge&#039;s Blog</description>
	<lastBuildDate>Tue, 15 Jun 2010 00:50:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>DependencyProperty Serialization</title>
		<link>http://www.emphess.net/2008/11/25/dependencyproperty-serialization/</link>
		<comments>http://www.emphess.net/2008/11/25/dependencyproperty-serialization/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 00:24:56 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[DependencyProperties]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Serialization]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=41</guid>
		<description><![CDATA[Ok, I did it: I tried to do it the easy way &#8212; serialization! And I quickly ran into the following issue: Serializing DependencyObjects. There are a lot of sources saying &#8220;you can&#8217;t serialize dependency objects&#8221;, which is true, but you can get pretty close rather quickly and it might not be the worst decision. [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, I did it: I tried to do it the easy way &#8212; serialization! And I quickly ran into the following issue: Serializing <code>DependencyObjects</code>. There are a lot of sources saying &#8220;you can&#8217;t serialize dependency objects&#8221;, which is true, but you can get pretty close rather quickly and it might not be the worst decision. </p>
<p>In this article, we&#8217;ll explore if and how reflection magic can assist us in doing it anyway, how we can locate <code>DependencyProperties</code> via reflection and what pitfalls remain. Moreover, I&#8217;ll give an outlook why the most desireable solution (that almost suggests itself) fails.</p>
<p><span id="more-41"></span></p>
<p>Using DPs in your business logic layer is a disputable decision. The application I work on has very unsual demands and I am still happy with the decision I made. I don&#8217;t want to discuss that here, though, since it is out of scope. </p>
<h2>The Issue</h2>
<p>When serializing objects, you can prevent certain properties from being serialized using the <code>[NonSerialized]</code> property, but if the base class is not marked as <code>[Serializable]</code>, such as the <code>DependencyObject</code> class, attempting to serialize will throw an exception.</p>
<p>However, implementing <code>ISerializable</code> manually does the job:</p>
<pre class="brush: csharp">
[Serializable]
public class SerializableDependencyObject : DependencyObject, ISerializable
{
    // Note that this does not call base(info, context) since the base class does not have
    // a deserialization constructor
    public DagNode(SerializationInfo info, StreamingContext context)
    { }

    // again, the base class is not an ISerializable
    public virtual void GetObjectData(SerializationInfo info,
                                                 StreamingContext context)
    {}
// ...
}
</pre>
<p>What bugs me, however, is that now, all derived classes need to implement <code>GetObjectData </code>and the deserialization constructor explicitly, producing both stupid and error-prone code:</p>
<pre class="brush: csharp">
public class StupidClass : SerializableDependencyObject
{
  #region ISerializable Members
  public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
  {
    info.AddValue(&quot;PropertyA&quot;, mPropertyA);
    info.AddValue(&quot;PropertyB&quot;, mPropertyB);
    info.AddValue(&quot;PropertyC&quot;, mPropertyC);
  }

  public StupidClass (SerializationInfo info, StreamingContext context)
  {
    mPropertyA = info.GetDouble(&quot;PropertyA&quot;);
    mPropertyB = info.GetDouble(&quot;PropertyB&quot;);
    mPropertyC = info.GetDouble(&quot;PropertyC&quot;);
  }
  #endregion
}
</pre>
<p>We obviously don&#8217;t want this, since it produces a lot of manually written, error-prone code that needs to be adjusted constantly when code changes are made &#8211; a lot of work when you consider we&#8217;re not necessarily adding functionality yet.</p>
<h2>One Step Back: .NET Serialization</h2>
<p>It took me some time to realize that .NET has quite a number of techniques aimed at serialization. The process is described quite well at <a href="http://msdn.microsoft.com/en-us/library/tyf8zbfk.aspx">http://msdn.microsoft.com/en-us/library/tyf8zbfk.aspx</a>, but it is still simplified since there are serialization attributes introduced in .NET 2.0 that allow you to hook up additional methods during the serialization/deserialization process:<br />
&#8220;If the class being deserialized implements the <code>IDeserilizationCallback</code>, the <code>OnDeserialization </code>method is automatically called when the entire object graph has been deserialized.&#8221; (see <a href="http://msdn.microsoft.com/en-us/library/ty01x675(VS.71).aspx">http://msdn.microsoft.com/en-us/library/ty01&#215;675(VS.71).aspx</a>)</p>
<p>These concepts are somewhat different and allow you to control the process of serialization and deserialization to a certain degree.<br />
You might be tempted to ask: &#8220;Why should I worry about .NET serialization if it is this complicated &#8211; isn&#8217;t it easier to do it myself?&#8221;, but the answer is probably &#8220;no&#8221;, since the <code>BinaryFormatter</code> really solves all the itty-gritty problems for you in a convenient manner. These are:</p>
<ul>
<li>Solving dependency chains and circular links</li>
<li>Creating unique identifier and associating them w/ object instances</li>
<li>Serializing generic containers</li>
<li>Constructing objects on de-serialization and re-assigning pointers</li>
</ul>
<p>All this does not help in serializing <code>DependencyProperties</code>, however, since your owning class is derived from <code>DependencyObject</code>, that is not marked as <code>[Serializable]</code> &#8211; unless you want to do it manually in each derived class.</p>
<h2>An intelligent base class</h2>
<p>How about a very intelligent base class that uses reflection to mimick the behaviour we&#8217;d expect?</p>
<p>We&#8217;d certainly need a class that is responsible for this behaviour, we might want to call it <code>SerializableDependencyObject</code> again:</p>
<pre class="brush: csharp">
[Serializable]
public class SerializableDependencyObject : DependencyObject, ISerializable
{
}
</pre>
<p>Now, the class needs to implement <code>ISerializable</code> in a sufficient manner, that is, in such way that derived classes behave just like normal serializable classes:</p>
<ul>
<li>The value of <code>DependencyProperties</code> is being stored and restored automatically</li>
<li><code>DependencyProperties</code> marked as <code>[NonSerialized]</code> are not being serialized</li>
</ul>
<h2>The GetObjectData method</h2>
<p>Let&#8217;s try to fetch all fields and properties from the current object instance (<code>this</code>) in the base class. We want to add all these fields to the <code>SerializationInfo</code> instance:</p>
<pre class="brush: csharp">
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
  PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(GetType(),
        new Attribute[] {
            new PropertyFilterAttribute(PropertyFilterOptions.SetValues |
                                        PropertyFilterOptions.UnsetValues |
                                        PropertyFilterOptions.Valid ) });

  List&lt;FieldInfo&gt; fieldInformation =
    ReflectionHelper.GetFieldInformation(GetType());

  foreach (FieldInfo fiRover in fieldInformation)
  {
    object[] attribs =
      fiRover.GetCustomAttributes(typeof(NonSerializedAttribute), false);

    if (attribs.Length &gt; 0)
      continue; // Don&#039;t serialize this

    info.AddValue(fiRover.Name, fiRover.GetValue(this));
  }

  foreach (PropertyDescriptor propertyDescriptor in descriptors)
  {
    if (propertyDescriptor.Name == &quot;Dispatcher&quot; ||
        propertyDescriptor.Name == &quot;DependencyObjectType&quot; ||
        propertyDescriptor.Name == &quot;IsSealed&quot; )
          continue;

      SerializeProperty(info, propertyDescriptor);
  }
}
</pre>
<p>The first loop of the method will serialize all fields, resembling the functionality we have when not implementing <code>ISerializable</code> manually. The second part, adding functionality, cares for <code>DependencyProperties</code>. The <code>ReflectionHelper</code> is just a simple wrapper around the <code>System.Type.GetFields()</code> method with some performance improvements and minor tweaks.</p>
<p>Let&#8217;s have a look at the serialization constructor of <code>SerializableDependencyObject</code>:</p>
<pre class="brush: csharp">
public SerializableDependencyObject(SerializationInfo info,
                                     StreamingContext context)
{
    Type thisType = GetType();

    // De-Serialize Fields
    List&lt;FieldInfo&gt; fieldInformation =
        ReflectionHelper.GetFieldInformation(thisType);

    foreach (FieldInfo fiRover in fieldInformation)
    {
        object[] attribs =
          fiRover.GetCustomAttributes(typeof(NonSerializedAttribute), false);

        if (attribs.Length &gt; 0)
            continue; // Don&#039;t try to deserialize this

        fiRover.SetValue(this, info.GetValue(fiRover.Name, fiRover.FieldType));
    }

    // De-Serialize DependencyProperties
    PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(thisType,
        new Attribute[] {
           new PropertyFilterAttribute(PropertyFilterOptions.SetValues |
                                       PropertyFilterOptions.UnsetValues |
                                       PropertyFilterOptions.Valid) });

    foreach (PropertyDescriptor propertyDescriptor in descriptors)
    {
        if (propertyDescriptor.Name == &quot;Dispatcher&quot; ||
            propertyDescriptor.Name == &quot;DependencyObjectType&quot; ||
            propertyDescriptor.Name == &quot;IsSealed&quot;)
            continue;

        DependencyProperty dp =
          DependencyPropertyHelper.FindDependencyProperty(this, propertyDescriptor.Name);

        if (null != dp)
            SetValue(dp, info.GetValue(propertyDescriptor.Name, propertyDescriptor.PropertyType));
        else
            throw new SerializationException(String.Format(@&quot;Failed to deserialize
            property &#039;{0}&#039; on object of type &#039;{1}&#039;. Property could not be found.
            Version Conflict?&quot;,
            propertyDescriptor.Name, thisType));
    }
}
</pre>
<p>Again, the first loop handles simple fields while the second part adds functionality for <code>DependencyProperties</code>. One line in the second part deserves some attention: </p>
<pre lang="csharp">
DependencyProperty dp =
  DependencyPropertyHelper.FindDependencyProperty(this, propertyDescriptor.Name);
</pre>
<p>Remember <code>DependencyProperties</code> are static members which are registered in some application-wide registry, for example:</p>
<pre class="brush: csharp">
public static DependencyProperty NameProperty =
DependencyProperty.Register(&quot;Name&quot;,
                            typeof(string),
                            typeof(GraphNode),
                            new PropertyMetadata(String.Empty));
</pre>
<p>Unfortunately, there is no <code>DependencyProperty.Find()</code> method. That is where the <code>DependencyPropertyHelper</code> comes into play:</p>
<pre class="brush: csharp">
class DependencyPropertyHelper
{
    /// &lt;summary&gt;
    /// Finds a dependency property on an object by its name.
    ///
    /// Motivation: There is no accesible DP registry. When creating DPs, one must register them using
    /// DependencyProperty.Register(), but there is no DependencyProperty.FindProperty()
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;_object&quot;&gt;The object that supposedly has a property of the supplied name&lt;/param&gt;
    /// &lt;param name=&quot;_propertyName&quot;&gt;The name of the property to find, e.g. &quot;Height&quot;. NOTE: The corresponding property is expected to be named &quot;HeightProperty&quot; in this case.&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public static DependencyProperty FindDependencyProperty(object _object, string _propertyName)
    {
        if (null != _object &amp;&amp; !String.IsNullOrEmpty(_propertyName))
        {
            Type typeAttachedTo = _object.GetType();
            FieldInfo fi = null;

            while (null == fi &amp;&amp; typeAttachedTo != null)
            {
                fi = typeAttachedTo.GetField(_propertyName + &quot;Property&quot;);
                typeAttachedTo = typeAttachedTo.BaseType;
            }

            if (null != fi)
            {
                return fi.GetValue(null) as DependencyProperty;
            }
        }
        return null;
    }
}
</pre>
<h2>First results</h2>
<p>At this point, we can supply a base class <code>SerializableDependencyObject</code> that allows simple serialization of <code>DependencyObjects</code> with their associated <code>DependencyProperties</code>. However, quite a number of dangerous pitfalls remain:</p>
<ul>
<li>Setting <code>DependencyValues</code> can be problematic: We might trigger callbacks (<code>PropertyChangedCallbacks</code>, <code>CoerceValueCallback</code>)</li>
<li>Triggered callbacks might rely on yet unitialized data</li>
<li>We rely on the &#8220;Property&#8221; naming convention (e.g. the DP of property <code>"Name"</code> is called <code>"NameProperty"</code>)</li>
<li>You need to define a deserialization constructor for each and every derived class which needs to call the base class&#8217; deserialization constructor. Failing to do so throws a run-time exception.</li>
<li>The current code does not handle versioning</li>
</ul>
<h2>Outlook</h2>
<p>Serializing dependency properties is indeed cumbersome. However, <code>INotifyPropertyChanged</code> might not be an alternative, and reinventing the wheel might not be desirable either. While basic functionality of <code>DependencyProperties</code> is probably quickly implemented, there are some obvious drawbacks, first and foremost the integration with other components that simply require a <code>DependencyObject</code> to work with.</p>
<p>Synchronizing a complex DataModel with sets of equally complex ViewModels can be a pain, too, so for those having such unusual demands, it&#8217;s their time to choose their poison.</p>
<p>In the second part, we&#8217;ll have a look at the <code>ISerializationSurrogate</code> interface and why we can&#8217;t implement it the same way we implemented the <code>SerializableDependencyObject</code>. We will also make the acquaintance of an infamous <code>InvalidOperationException</code>: &#8220;Current local value enumeration is outdated because one or more local values have been set since its creation.&#8221; which esentially keeps us (and probably microsoft) from implementing it just the way we did in here.</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=DependencyProperty+Serialization+http://bit.ly/9748ij" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/11/25/dependencyproperty-serialization/&amp;title=DependencyProperty+Serialization" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/11/25/dependencyproperty-serialization/&amp;title=DependencyProperty+Serialization" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/11/25/dependencyproperty-serialization/&amp;t=DependencyProperty+Serialization" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/11/25/dependencyproperty-serialization/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
