Thursday, May 05, 2005

One of my favorite new features available in the CF v2 is the XmlSerializer. Presence of it in the CF opens up a great possibilities in building a cross device/desktop communications (read WSE and such). But when you start using it you'd notice some lag when trying to serialize/deserialize your objects. It's explained by a way the XmlSerializer is designed. When you call its constructor:

new XmlSerializer(type, defaultNamespace)

the serializer walks the whole object graph using reflection and discovers all serializable properties and fields. Reflection as you know, due to its “late bound“ nature, is not the fastest part of .NET. So the solution could be caching the XmlSerializer for the object types that already have been used and re-use it for next time you need the serializer.

Here's the code for XmlSerializerCache class that you can use to achieve that:

public class XmlSerializerCache

{

      #region fields

 

      private static Hashtable table;

 

      #endregion // fields

           

      #region constructors

 

      static XmlSerializerCache()

      {

            XmlSerializerCache.table = new Hashtable();

      }

 

      private XmlSerializerCache()

      {

      }

 

      #endregion // constructors

 

     

      public static XmlSerializer GetXmlSerializer(Type type, string defaultNamespace)

      {

            XmlSerializer serializer;

            if (type == null)

            {

                  throw new ArgumentNullException("type");

            }

            // Make it thread safe

            lock (XmlSerializerCache.table.SyncRoot)

            {

                  string typeName;

                  if ((defaultNamespace == null) || (defaultNamespace.Length == 0))

                  {

                        typeName = type.FullName + "#";

                  }

                  else

                  {

                        typeName = type.FullName + "#" + defaultNamespace;

                  }

                  // Try to get the serializer from cache

                  object obj = XmlSerializerCache.table[typeName];

     

                  if (obj == null)

                  {

                        // We don't have it, create a new instance

                        obj = new XmlSerializer(type, defaultNamespace);

                        XmlSerializerCache.table.Add(typeName, obj);

                  }

                  serializer = obj as XmlSerializer;

            }

            return serializer;

      }

}

 

The usage of the XmlSerializerCache should be pretty straightforward:

 

XmlSerializer serializer = XmlSerializerCache.GetXmlSerializer(typeof(Order), "http://tempuri.org/");

 

serializer.Serialize(stream, order);

 

BTW, you can employ this class for the desktop .NET as well too and enjoy some speed improvements.

5/5/2005 4:31:20 PM (GMT Daylight Time, UTC+01:00)  #     |