I'm trying to create a function that will save the current state of my application to a file, and another function to load a saved file. Currently, all the information is contained within a single object, which in turn refers to other objects. I recently heard that C# has some built-in classes that help you serialize and deserialize your objects, so I did a little research and learned about DataContracts, mostly from this page: http://msdn.microsoft.com/en-us/library/ms731073.aspx
Most of it works, except for the classes that implement built-in classes. For example, I have an object that inherits System.Windows.DependencyObject, and when I try to serialize it, it complains that my class inherits a class that does not have the DataContract attribute.
It makes sense to me why that would be a problem. When an object is being deserialized, its constructor is not called. If it inherits something that is not serializable, that might leave it in an invalid state.
I was wondering if this was possible: can I somehow tell the deserializer to call the base class's default constructor before deserializing my object? And then I would have to tell the serializer not to freak out.
Can you create a data transer object that has all the properties you want to store, then populate that object with data from the framework object? Mark it as serialized, fire up the serialization class of your choice - and now you have all the info you need. You just need to re-populate the appropriate class after deserialization.
You may want to look into using a binary serializer or xml serializer instead of a data contract serializer for this one. If you're saving it to a file and don't need the file human-readable binary serialization nearly always works.
See Binary Serialization, and in particular the Basic Serialization topic.
Also take a look at the XmlSerializer Class which will sometimes work where a DataContractSerializer doesn't.
Related
I have an entity class which can change over period of time. As of now, I binary serialization to serialize an object of this class. But if I add a new property to the class, I can't deserialize a stream serialized earlier. I tried if I can use BSON with json.net.
I need to take care of these things:
Memory footprint of serialized data should be low
serialization and deserialization should be fast
Need to provide backward compatibility for data serialized with old entity class structure
One approach I considered is to convert the object to IDictionary before serializing it so that I can set default value to properties that are not matching while deserializing. While this works well, it involves additional step to convert the object to IDictionary.
Has anyone faced this situation? what are the approaches you use?
Actually binary serialization is very flexible. Of course, you can just add [Serializable] attribute to the class and forget about details, but you can also take the full control on serialization by implementing ISerializable interface/by adding methods/attributes which corresponds to the certain steps of serialization/deserialization lifecycle. Considering your question about structure changes, please take a look on the following article.
I have long held the believe that your domain model should not be responsible for serializing itself to XML. I have used the IXmlSerializable interface in the past to control how my objects are serialized but ideally I'd prefer the nuts and bolts of the serialization to live outside the object.
However I've never been able to actually implement this in a clean manner and I was wondering if there was any patterns I was overlooking to make this happen. Basically I want my object model to do it's thing and be oblivious to XML serialization (or any other serialization for that matter) and then handed off to some service that spiders the object and serializes it.
I've tried doing this with extension methods but this falls short when you want to serialize a collection of type object. I've looked at doing it with object wrappers and DTO's that then serialize but then you've got the overhead of maintaining another set of objects and having to create these objects when you want to serialize which again can get messy when you have collections of type object.
The only other thing is using reflection but I'd worry about the processing overheads.
Is there a sane way to do what I'm asking or should I just bite the bullet and make my objects xml aware?
Using the System.Xml.Serialization Attributes is putting the nuts and bolts outside of your code. You are defining metadata and with the exception of optional parameters, no extra code is required. Implementing IXmlSerializable and doing the serialization by hand is error prone and should be avoided. Why? You are defining your data 3 times.
XML Schema
Class
Serialization code
Using attributes, you can scrub step 3.
XML and C# has an impedance mismatch. Like it or not, at some point, you will need to define the serialization to create the right document model.
Arguably, the classes you are serializing should not be performing any work. They are just a data store. Try abstracting your logic away from serialized objects - it may give you a warmer feeling.
Update
If you really, really hate attributes, try using the adapter pattern to serialize your model. The XML code will be in a separate class or assembly and you can work with your model across storage mediums. You will suffer the consequence of having to update the serialization separately when you update your model.
Im trying to store my data in an XML file using the XML Serialization. Question is, if my object has a collection member, can i serialize the collection as well?
This is how my objects work.
class Project{
List<Iteration>
}
class Iteration{
List<Job>
}
class Job{
some other attributes
}
So each project has a list of iterations, and each iteration has a list of projects. So essentially, Each project can have many iterations and each iteration can have many jobs.
If serialization is not possible, can anyone suggest to me another method to store my data?
thanks in advance.
I have used such a type of serialization before. If you have a simple application you can sometimes serialize your whole set of data from one root object (might be an antipattern somehow, but I know I have done it before).
This should work with the default XML serializer in the XML.Serialization namespace, but you need to make sure your classes are marked with the serializable attribute. I'm not sure if it is available on the compact framework though.
Have you considered using Json serialization instead? If you use something like Json.Net (available for Windows Phone 7), you should be able to serialize the entire object graph.
I have 3-rd party dll. From that I receive an object of some type (I know its interface, but not all the object). That object is not marked as serializable and I'm not related to that libruary development at all.
I want to serialize it to some storage and then receive it from storage with the same state later (public/private, references etc.). I got here one option - make my own serialization mechanism that will act the same as .NET serializers with the only difference - it won't revise serialization attributes.
Is that the best way?
Thanks.
You can use XmlSerializer or DataContractSerializer to serialize types not marked with SerializableAttribute.
There may be other options. And can always go ahead with custom implementation if nothing works for you.
You can make your own class inheriting from that object and serialize it.
OR you can make your own replica of that class and make some explicit (or implicit, but not recommended) conversion methods.
I have read around that serializing generic classes is not supported out of the box with XamlWriter.
First I would like to know why? What is harder about generic classes that makes them non-plug-and-play like all the other classes are.
Second, is there a framework that will allow me to serialize my generic class without much work. (My generic class is fairly involved.)
XamlWriter is hardly the standard serialization method (unless something changed and no one told me!). You haven't actually mentioned what kind of format you want to serialize into, but since you mentioned Xaml I will assume Xml.
For this you can use the DataContractSerializer. It shouldn't have any problems with generic types, and isn't very difficult to use at all. Just remember to markup your class with DataContract and DataMember attributes, just as if you were using WCF.