views:

235

answers:

1

If I have a class named "MyClass" in an assembly named "AssemblyA" and serialize it to a file using .NET's BinaryFormatter. Then move the code of "MyClass" into an assembly named "AssemblyB" and try to deserialize the file I get the following "System.TypeLoadException" exception:

Could not load type 'AssemblyA.MyClass' from assembly 'AssemblyA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Is there any way for me to indicate that the class has been moved to AssemblyB? Via an attribute of some sort? Or is it possible to modify the serialised file as a pre-preprocessing step to change all references from AssemblyA.MyClass to AssemblyB.MyClass? Finally, if neither of those options are possible, is it possible to bypass trying to deserialise this class and continue deserialising the rest of the data anyway?

+1  A: 

If you have moved it, then add a reference to the dll where it now resides, and use TypeForwardedToAttribute:

[assembly:TypeForwardedTo(typeof(TheType))]

This will be enough for some requests (including BinaryFormatter IIRC) looking for a type to find it in the new assembly. However, IIRC it only works for outermost types (not nested types, and probably not generics), and you can't have renamed it / changed the namespace / etc.

Renaming is tricker... BinaryFormatter is notoriously brittle about such things. IMO, it is only suitable for serializing transient data between two tightly coupled systems (for example, exchange between two AppDomains in the same process; when used for storage, or between systems that might get out of sync, it can be a nightmare.

It may be too late, but I would recommend using a contract-based serializer (rather than a type-based serializer); any of XmlSerializer, DataContractSerializer (as long as you use the [DataContract]/[DataMember] attributes), etc. Of if you want fast binary, protobuf-net would do a good job (and can hook into ISerializable if you need).

Another concept that might be worth looking at is serialization surrogates, but that is relatively hard. But IIRC this gives you the control over the type that is created - but you need to do a lot of the work for it.

Marc Gravell