ISerializable - Serializing singletons - c#

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

Related

object reference vs an interface reference

Difference between accessing an object’s methods with an object reference vs an interface reference, even if both refer (point) to the same object.
I dont know what is object
referene and interface reference please explain?
If you have a reference to an object using an interface, you will only have access to that objects methods or properties that are defined in the interface. If you need to access any additional methods, you have to identify the specific type of the implementation, and cast it to that type before calling those methods or properties.
Using the interface type instead of the actual type is often done to reduce coupling between objects. For example, one of your objects that are logging something might need an instance of ILogger, but it should not really care if the implementation of ILogger logs to a file, to a web-service or does something else. It should only care about getting an object that fullfills the contract that the interface defines.
If I understand you question correctly you are asking the difference between object of a class and object of an interface
Object of a class contains full implementation of the class. You will be able to call all the public methods and use public fields of that class through the class object.
On the other hand, interface object only exposes those methods and fields which are defined by interface.
One case is when you know the type of your object (so the class your object is an instance of) and this way you can access all its methods. Let me stress that again: you know the class of the object.
Second case is when you only know that your object implements an interface, you do not know which class your object is. This way you only have access to the methods that the class inherits from that particular interface, and no other method.
It's actually very simple. When you access object methods, with interface reference you can only access the methods that are part of that interface definition which are implemented by that object's class.
And when you access them with class reference then you can access all that are part of the class.
Actually with interface you don't care what is the actual class of that object, you only want to be concerned with the interface methods, that are implemented in that class, so you can access only those..

How to implement saving/loading interface with parameterized constructor?

I know interfaces cannot define constructors. Here's what I wish I could do:
public interface SavableObject {
void Save(ObjectSaver saver);
SavableObject(ObjectLoader loader); //This, obviously, doesn't work
}
//Loading an object inside ObjectLoader:
T LoadObject<T>() where T : SavableObject {
return (T)Activator.CreateInstance(typeof(T), this);
}
And I could do this if I took out the line that didn't work, and there would just be a runtime error when trying to load (or possibly save, if I put an assert in there) the object if it didn't have the constructor. I'm just wondering if there's any way to require a class to have a particular constructor that can be used with the Activator. Can I use a custom attribute somehow, and require that attribute to be on the class? Or must I rely on runtime checks to load and save data?
I know I could have a parameterless constructor and a Load(ObjectLoader) method but I don't necessarily want to have a parameterless constructor available to abuse for other purposes.
what about ISerializable?
In brief I suggest you use generics as most factories do.
public interface SavableObject<T> : where T : new
{
void Save(IObjectSaver<T> saver);
SavableObject<T> Load(ObjectLoader loader); //This, obviously, doesn't work
}
However, you seem to have turned it on it head. The class is doing what factory must do. So I do not think it is such a good idea to pass the factory to the entity itself and that is part of the problem you are experiencing in the design.
If you are not afraid of using Reflection, like Activator that you have shown, you can do little trick I tend to use:
Make parameterless constructor that is protected
Make Load method, that is also protected (or private, I tend to use virtual protected so I support inheritance)
Create new object using this non-public constructor (through reflection - you can't create instance of your class "just like that" using new operator)
Invoke load method (also using reflection - no one will call it later).
I don't know if this will work for you, but I used that method when I needed to deserialize pretty big game state and it was pretty fast, eventhough all this reflection (for many reasons I did not wanted to use built-in serialization methods and Factory Pattern wouldn't do, so I tend to treat this method as something that may be useful if other methods fail, on the other hand, if I could - I would probably use built-in serialization for simplicity).
How about adding a property on your interface:
public interface SavableObject
{
void Save(ObjectSaver saver);
ObjectLoader ObjectLoader {get; set;}
}
Then in your factory:
T LoadObject<T>() where T : SavableObject
{
var result = (T)Activator.CreateInstance(typeof(T));
result.ObjectLoader = this;
return result;
}
Based on your question and comments.
I think you should do it at runtime using reflection.
Combining constructors and interfaces is ilogical from its core. Interface is about what concrete instance can do, not how to initialize it. This can only be achived using abstract class.
Maybe using factory to create instance of the class?
Also I don't think you can get better speed than default ISerializable implementation. Unless you are .NET GURU and have years of time for it.
Short answer: It's not possible, I guess. There are no attributes or generalizations I can use to require a specific kind of constructor on a class.

Reinject dependencies of a freshly deserialized object

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.

Is it possible to use Protobuf-Net with a class without a parameterless constructor?

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).

What is the best way to ensure that all necessary class properties are set before returning an object which will be used somewhere else

I have a class that requires a specific method to be called before being used by other objects, this method implements all the required logic and sets the properties of the class to their respective values. How can I ensure that the method of this class is called before the object is returned for use by other objects? I heard that it is a bad idea to implement logic in the constructor so I cannot call this method in the constructor. A code example for this sort of implementation is as follows:
SomeClass myClass = new SomeClass("someName");
//Class must call this method if object is to be of any use
myClass.ConvertNameToFunnyCharacters();
return myClass;
If it's essential that the object is constructed correctly then it's not a bad idea to put the logic in the constructor. You should consider putting the logic in another method - which should be public if you want to be able to "reset" the object back to its default state.
If that method needs to be called before the class can be used then it sounds to me much like what a constructor should be doing. And a constructor is also just a special method, so what should be wrong about "implementing logic in the constructor"?
Make your constructor internal, protected or private according to your needs and implement a Factory pattern.
This is how to proceed when you need some object initialization to avoid high object dependencies.
http://msdn.microsoft.com/en-us/library/ms954600.aspx
Putting a lot of logic in the constructor can lead to a few problems:
If the constructor calls methods of the object, those methods run in a partially constructed object. This can really bite you when you override the method in subclasses: in Java and C# the subclass' implementation will run before the subclass' constructor has initialised the extended state of the object and so fail with null pointer exceptions. C++ works more "correctly" but can cause different confusing effects.
It makes unit testing with mock objects a bit more complicated if the constructor calls back out to objects passes as parameters.
So, I prefer to keep constructors as simple as possible: just assign parameters to instance variables. If I need to perform more complex logic to initialise an object I write a static factory function that calculates the constructor parameter values and passes them to a simple constructor.
The reason it isn't recommended to have a lot of logic in the c'tor is that while in the c'tor the object still isn't valid. If that's what your "other" method does, then it's fine as part of the c'tor.
According to me I will call it in the constructor or you'll make a burden on the class user to call this method before using it

Categories

Resources