If a program has literally just deserialized an object (doesn't really matter how, but just say BinaryFormatter was used).
What is a good design to use for re-injecting the dependencies of this object?
Is there a common pattern for this?
I suppose I would need to wrap the Deserialize() method up to act as a factory inside the container.
Thanks!
You shouldn't serialize objects with dependencies that can't themselves be serialized.
Instead, split it into two classes: extract the serializable parts into a separate class.
After deserializing, you can associate the resulting object with an instance of the original class (the one with dependencies).
I would use the OnDeserialized attribute to point at a method that would do the re-injection.
Unity has a concept of "BuildUp" where you can ask it to fulfil the dependencies of an existing object. I don't know if autofac (which I presume you are using from the tags) has an equivalent.
Related
Serialization woes continue...
I'm trying to serialize a class, instances of which share between them common objects (a binder of sorts). So, objects A, B, C share object Binder1, and objects D and E - Binder2, and so on... I'm serializing objects A,B,C,D,E. Typically, this binder object is passed in a constructor - not with the serializer though, since it needs a parameterless constructor.
ISeriazable seems to have something that works for singletons - IObjectReference interface, where the method GetRealObject can be used to return a reference to the newly created singleton. But, it doesn't look like XmlSerializer cares about this interface.
So, how should I go about serializing/deserializing these objects?
EDIT: I'm almost ready to give up on this question, since I just discovered this question discussed on a forum from 2006 (!!) between two giants #JonSkeet and #MarcGravell, where the answer is essentially no for XmlSerializer. I'll keep this question open for a bit longer just in case things have changed in the past 7 years.
I haven't found a way to do this natively with XmlSerializer. I did find an old thread between Jon Skeet and Marc Gravell that basically says that you can't do this the same way that you could with ISerializable and IObjectReference.
The way I had to make this work was along the following lines:
Add a Guid field to the Binder object (i.e. the common object shared by multiple objects)
During deserialization, use a static Dictionary and either use an already registered Binder object with the same Guid or add a new Binder object to the static dictionary for others to link against.
The ISerializable interface only provides a method to serialize the object. The deserialization
process is managed by a constructor.
The problem is, that constructor cannot return an instance, because the constructor CREATES a new instance.
In my implementation, there are several attributes corresponding to singletons instantiated and maintainded somewhere else.
I need the deserialization process to get that instance and assign to the attribute, instead of creating a new instance.
The constructor approach is not suitable for this.
In Java, you would call the ReadResolve() method, is there a C# equivalent?
You need to make your classes which save a reference to the singleton implement IObjectReference.
Take a look at http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iobjectreference.aspx
Using Protobuf-Net, I see that it does not seem possible to deserialize a class without having a parameterless constructor or I may be missing something?
I don't want some of the classes with a parameterless constructor. Is there some kind of attributes that I could use or some other technique?
protobuf-net depends currently on having a parameterless constructor to work.
However that constructor need not be public (it will use reflection if need be to invoke it) so you may be able to define the required private constructor just for use by protobuf-net (adding a comment as to why) and deal with specific serialization related issues there.
This keeps the rest of your api from being able to construct 'illegal' instances.
Marc points out that if you are talking about the outermost message object, you could also create the object yourself and call Serializer.Merge. But if it needs to create an object (because it currently has a null instance, or for new items in a list/array), then it looks for a default constructor.
ShuggyCoUk is right about it using the parameterless constructor.
Just for completeness, though - if you are talking about the outermost message object, you could also create the object yourself and call Serializer.Merge. But if it needs to create an object (because it currently has a null instance, or for new items in a list/array), then it looks for a default constructor.
I suppose that I could also provide some markup in the attribute to say "just create a raw object via FormatterServices", but this feels unnecessary (compared with a private parameterless constructor), and may not work on all platforms (Silverlight, CF, etc - being likely problems).
Are there any closed or open source projects for a XML serializer for C# that can serialize for the most part any object without the need to pollute my domain objects with tons of attributes? That will also handle serialization of collections built with the internal generics classes? A bonus would be that it can handle serializing an interface type property. Another bonus would be that it can serialize objects that have read-only properties (or atleast with the get accessor marked internal)
Well, first define "advanced", i.e. what specifically do you need that XmlSerializer doesn't have. In terms of POCO, XmlSerializer has an overloaded ctor that accepts all the attributes you could ever want to add, to avoid having to add them to your object model - but it does still require a public parameterless constructor, and only works on public read/write fields/properties. And you should cache/re-use the serializer if you use this approach.
I'm not aware of any like alternatives, simply because in most cases this is "good enough" - and it is often a mistake to try to brute-force your existing domain object into a DTO. It may be simpler and more maintainable to simply map your domain entities onto a new DTO(s) that are attributed (and have appropriate ctor/properties/etc).
Note that for the ctor/properties issue DataContractSerializer has some answers, but this doesn't have as much fine-grained control over what the xml looks like.
You can allow System.Xml.dll to access your internals by using the InternalsVisibleToAttribute.
Thus serializing internal types and/or internal members. Including internal .ctors.
You can also implement IXmlSerializable on classes to customize their serialization (like the container containing interface references).
You do not have to provide the XML serialization attributes on your classes, but provide them as XmlAttributeOverrides instead.
XmlSerializer is almost always exactly what people want, they just don't know that it is as flexible as it really is.
Greetings,
I have a particular object which can be constructed from a file, as such:
public class ConfigObj
{
public ConfigObj(string loadPath)
{
//load object using .Net's supplied Serialization library
//resulting in a ConfigObj object
ConfigObj deserializedObj = VoodooLoadFunction(loadpath);
//the line below won't compile
this = thisIsMyObj;
}
}
I want to, in essense, say "ok, and now this object we've just deserialized, this is the object that we in fact are." There are a few ways of doing this, and I'm wondering which is considered a best-practice. My ideas are:
Build a copy-into-me function which copies the object field by field. This is the current implementation and I'm pretty sure its a horrible idea since whenever a new member is added to the object I need to also remember to add it to the 'copy-into-me' function, and there's no way that's maintainable.
Build a static method for the ConfigObj class which acts as a de-facto constructor for loading the object. This sounds much better but not very best-practice-y.
I'm not entirely happy with either of the two, though. What is the acknowledged best practice here?
Your second option is what is called a factory method and is a common design technique. If you do use this technique, you may find that you need to know the type of class you will load before you actually load the class. If you run into this situation, you can use a higher level type of factory that looks at the stream and calls the factory method for the appropriate type of class.
There's nothing wrong with having a static method instead of a constructor. In fact, it has a number of advantages.
I always go with the static method. Usually it's kind of a hierarchy which is loaded, and therefore only the root object needs the method. And it's not really an unusual approach in the .NET framework (e.g. Graphics.FromImage), so it should be fine with users of your class.