Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing a serialized object between applications

In application 1 I serialize and deserialize and object and it works fine. I would like however to deserialize an object from application 1 in application 2. I added the class that defines that object to application 2. When I try to deserialize it I get this error:

Could not find assembly 'WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

How do I share a serialized object between two applications then?

like image 262
ZviBar Avatar asked May 08 '13 09:05

ZviBar


People also ask

Can a serialized object be transferred over a network?

Using serialization, an object can be transferred across domains through firewalls, as well as be used for different languages and platforms. The formats of serialized objects are standardized so as to be able to be read by different platforms, if needed.

What happens if the object to be serialized?

To serialize an object means to convert its state to a byte stream so way that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java.

Why do we have to serialize data before we can send it to another computer?

To wit, serialization is the process of converting a data object into a byte stream, and saving the state of the object to be stored on a disk or transmitted across a network. This cuts down the storage size needed and makes it easier to transfer information over a network.

Can we transfer object without serialization?

You don't always require serialization/deserialization. If you're sending an object over a network, then it gets serialized to send it via a byte stream. That's the point of serialization, precisely so that you CAN send via a network.


2 Answers

Put the definition for the serializable object into a separate assembly and then add a reference to the shared assembly to each project. (The formatter is adding a reference to the assembly in your first project - they must in fact refer to the same class, not just an identical copy of the class)

like image 59
Nathan Avatar answered Sep 19 '22 22:09

Nathan


If you are using BinaryFormatter, then it includes the full type name in the data, which includes the assembly that the DTO is in (types are always defined by their assembly). One option here is to create a separate DTO library that you reference from each - but note that BinaryFormatter is still pretty unreliable when it comes to versioning: I have seen people lose data because they edited their DTO and everything stopped working.

I would strongly advise using a non-type-dependent serializer; for example, XmlSerializer / DataContractSerializer / JSON.NET / ServiceStack's JsonSerializer, or protobuf-net. All of these will work fine but importantly will not fight you, in two different ways:

  • they are very versioning-friendly
  • they don't care if you move types between assemblies

Even with this, it is probably most convenient to maintain a separate DTO assembly for the serialized types, but it doesn't force you to. Ultimately, since these serializers are all happy to work cross-OS / cross-version / cross-language / cross-CPU, the mere fact of "different assemblies" is very much a "meh, whatever".

Key takeaway: BinaryFormatter can be brittle. I never recommend it for anything except in-flight data (for example, remoting between two AppDomain instances). I certainly wouldn't use it for anything that is persisted for any length of time, because I simply can't guarantee that I'll be able to reload it in the future.

like image 29
Marc Gravell Avatar answered Sep 17 '22 22:09

Marc Gravell