views:

350

answers:

2

Hi Folks,

I serialize some configuration objects and store the result bytes within a database.

new BinaryFormatter().Serialize(memoryStream, instance);
Convert.ToBase64String(memoryStream.ToArray());

These objects will be deserialized later.

new BinaryFormatter().Deserialize(memoryStream);

It's possible, that the Application has some new assembly versions at the time of deserialization. In general it works well, but sometimes I get a file load exception: "The located assembly's manifest definition does not match the assembly reference.". The assemblies work all with strong naming, can that be the problem and how could I avoid this problem?

Thanks for help

A: 

I think WCF might be your best bet. It can handle passing unknown fields through to it's consumer even if it doesn't know how to deserialize them.

Example:

Service A: Knows about version 2 of the Widget class which has a Description field

Service B: Knows about version 1 of the Widget class which doesn't have a Description field

Service C: Knows about version 2 of the Widget class which has a Description field

If service A calls service B passing a Widget object and then service B calls service C passing on the same Widget object then service C will get the Description field as it was passed from service A. Service B won't have any Description field but when it deserializes it and re-serializes it it will just pass the Description field through without knowing what it is.

So, you could use WCF services with in-proc communication.

See this link for more on versioning wcf contracts.

Jonathan Parker
We already had problems with strong naming and WCF, additionally it would be an abstraction layer more, which only confuses the programmers.
Enyra
+1  A: 

Absolutely, using BinaryFormatter with database (i.e. long-term) storage is a bad idea; BinaryFormatter has two three big faults (by default):

  • it includes type metadata (shucks if you move/rename your types... this can mean strong name/versioning too)
  • it includes field names (fields are private details!)
  • it is .NET specific (which is a pain if you ever want to use anything else)

My blog post here raises two specific issues with this - obfuscation and automatically implemented properties... I won't repeat the text here, but you may find it interesting.

I recommend the use of a contract based serialization. XmlSerializer or DataContractSerializer would suffice normally. If you want small efficient binary, then protobuf-net might be of interest. Unlike BinaryFormatter, the binary from this is portable between implementations, extensible (for new fields), etc. And it is quicker and smaller, too.

Marc Gravell
The solution with the XmlSerializer I already had in mind, my fellow didn't implement it with two thoughts, 1. binary serialization is faster than contract serialization and 2. it's not human readable. It sounds weird, but we can not trust our own market support, they touch everything ^^. I'll have a look at your suggestions, perhaps I'll find a solution.
Enyra
On that: protobuf-net is faster than BinaryFormatter, still unreadable, and without all the pain-points of BinaryFormatter... Of course, compression would also make xml unreadable (as another possibility).
Marc Gravell