Please click this logo to help me get on their beta program:

Xobni outlook add-in for your inbox








10/2/2005

Persisting of unknown (or new) types with XPO

Filed under: Programming, .NET, XPO — Oliver Sturm @ 10:59 am - 3 years, 11 months ago

In XPO, an ORM product by Developer Express, it’s possible to use a custom “value converter” to persist information when the standard mapping techniques are not sufficient. This provides a flexible approach that can be used in many different scenarios.

Nullable types

Although the Developer Express knowledge base provides an article that shows how to persist a bitmap, I had never actually used that approach. With .NET 2.0, I was thinking about persisting nullable types and I found that XPO 1 doesn’t have support for that out of the box. The support guys sent me a sample showing how a value converter can be used to extend the mapping to include nullable types. I extended that code to create a generic value converter that can be used for any nullable type. Here’s the code for that:

Generic nullable type converter
  public class NullableValueConverter<T> : ValueConverter where T: struct {
    public NullableValueConverter( ) {
      storageType = typeof(T);
    }
	
    private Type storageType;
    public override Type StorageType {
      get { return storageType; }
    }
	
    public override object ConvertToStorageType(object value) {
      Nullable<T> nullableValue = (Nullable<T>) value;
      return nullableValue.HasValue ? (object) nullableValue.Value : null;
    }
	
    public override object ConvertFromStorageType(object value) {
      return (Nullable<T>) (value == null ? null : value);
    }
  }

Now how do you use that thing? It’s simple: just decorate a property that has a nullable type with the ValueConverterAttribute:

Setting the converter for a property
  private int? intVal;
  [ValueConverter(typeof(NullableValueConverter<int>))]
  public int? IntVal {
    get { return intVal; }
    set { intVal = value; }
  }

With newer versions of XPO (I’m not sure if that feature is in any released version yet, if it isn’t and you want it (and you are a customer), feel free to send mail to support@devexpress.com) you can also register the value converter for a type globally, so all properties of that type will be converted automatically. Here’s how:

Setting the converter for a specific type
  Session.DefaultSession.Dictionary.RegisterValueConverter(
    new NullableValueConverter<int>(), typeof(int?));

Unknown types

The second interesting use of the value converter was something I stumbled upon a few days later. I had a field in a class that should have been persisted, but I really didn’t know what that field might contain later on. The information would be sent to a server via Remoting and the type depended on the client implementation, so I could only use “object” as the type for the field. Now, how would I go about persisting this information?

The solution I found was to create a value converter that uses serialization to persist the object into a string field. Of course, the object has to be Serializable for this to work, but that’s a requirement for the Remoting part anyway, so I didn’t care. With my SerializableObjectConverter it’s possible to decorate a property like this:

  private object data;
  [ValueConverter(typeof(SerializableObjectConverter)), Size(SizeAttribute.Unlimited)]
  public object Data {
    get { return data; }
    set { data = value; }
  }

And here’s the code for the SerializableObjectConverter:

A converter for all serializable types
public class SerializableObjectConverter : ValueConverter {
  public override Type StorageType { get { return typeof(string); } }
	
  public override object ConvertToStorageType(object value) {
    Assert.Check(value.GetType().IsSerializable,
      String.Format("The given object ({0}) is not serializable.", value));
	
    string result = null;
	
    MemoryStream stream = new MemoryStream();
    try {
      SoapFormatter formatter = new SoapFormatter( );
      formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
      formatter.Serialize(stream, value);
      result = Encoding.Default.GetString(stream.GetBuffer( ));
    }
    finally {
      stream.Close();
    }
	
    return result;
  }
	
  public override object ConvertFromStorageType(object value) {
    object result = null;
	
    MemoryStream stream = new MemoryStream(
      Encoding.Default.GetBytes((string) value));
    try {
      stream.Position = 0;
      SoapFormatter formatter = new SoapFormatter();
      formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
      result = formatter.Deserialize(stream);
    }
    finally {
      stream.Close();
    }
	
    return result;
  }
}

4 Comments »

  1. Very nice - how about trying this with the BinaryFormatter.
    AFAIK it should take any object, serializeable or not.

    Comment by Kenneth Ellested — 10/2/2005 @ 1:23 pm - 3 years, 11 months ago

  2. I haven’t tried this right now, but this page in MSDN certainly suggests differently. Where have you heard or seen that the BinaryFormatter can serialize objects without the SerializableAttribute?

    Of course, using the binary format has its advantages because the stored data will be more compact and I guess the serialization process will probably be faster, too. But I usually prefer to use text (xml) based formats these days because memory and processing power aren’t the scarce resources they used to be. Plus, I can always look into the database with any tool and - more or less - read what’s in the field if it’s in SOAP format.

    Comment by Oliver Sturm — 10/2/2005 @ 1:43 pm - 3 years, 11 months ago

  3. I guess I have confused something then. I just remember an issue, trying to serialize some
    objects back in time when .net was initially released. It wasn’t possible without using the
    binary formatter. Maybe it had something to do with the object graph. Anyway, I haven’t had any
    use for it since, so until now I just believed that the binary formatter was capable of
    serializing any objects. Maybe I also confused it with the ISerializable interface.

    Comment by Kenneth Ellested — 15/2/2005 @ 12:26 pm - 3 years, 10 months ago

  4. […] under: Programming, .NET, XPO — Oliver Sturm @ 1:45 pm - 32 minutes ago In a previous article, I showed how nullable types, as implemented in version 2 […]

    Pingback by Oliver Sturm’s weblog - Nullable types in XPO without .NET 2 — 15/3/2005 @ 2:17 pm - 3 years, 9 months ago

RSS feed for comments on this post. TrackBack URI

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>


Powered by WordPress
© Copyright 2005-2008 Oliver Sturm