I'm having a problem with XML serializing and deserializing a class which contains a collection of instances of a concrete classes that implement a base abstract class.
My solution is organized like so:
- A class library project containing an abstract class called Base.
- Another class library project, which is used as a plugin, containing a concrete class called Derived which implements Base. I am going to have more than one project like this, because I'm going to load them as plugins on the main project.
- An app, which is the main project. It knows uses the first project as a reference, and loads plugin assemblies which export a concrete class that implement Base, like the second project, on runtime. On startup, after loading the assemblies using reflection, it loads serialized instances of classes which implement Base and deserializes them on shutdown.
Here's an example of my classes:
Lets say I have this abstract class in one project, called BaseClassProj:
public abstract class Base
{
public int BaseProp { get; set; }
}
I have another project, DerivedClassProj, in which I implement the Base abstract class, and add some properties:
public class Derived : Base
{
public string DerivedProp { get; set; }
}
And then there's a third and main project in which I have a class which contains a dictionary which key type is the name of the type which has to be some derived class of Base, and the value is a collection of instances of that given type. ObservableDictionary is XML serializable, implementation is here. For example:
public class Manager
{
public ObservableDictionary<string, ObservableCollection<Base>> Instances { get; set; }
}
The problem is that during runtime I load the types to my main project, so I won't know the type I'm about to load in advance which means I cannot use XmlInclude, which is why I'm using this:
// Type = Base, extraTypes = { Derived, [another derived class, ...] }
public XmlSerializer(Type type, Type[] extraTypes){..}
overload of XmlSerializer constructor in order to serialize and deserialize the main class.
When I tried to serialize the Manager class, an InvalidOperationException was thrown:
The type Derived (or any other concrete class that implements Base) was not expected. Use XmlInclude or SoapInclude attribute to specify types that are not known statically.
Just like I said, I do not know the types I'm handling when serializing and deserializing in advance because I load them on runtime using reflection, therefore I am not able to use XmlInclude attribute on Base class. The only thing I know before serializing or deserializing is that Base is assignable from the types I'm dealing with.
So, what can the problem be? I initialized XmlSerializer with typeof(Base) as the main type and an array of types of which Base is assignable.
Thanks in advance! I've been trying to figure out solutions for my requirements and searching all over the internet all day long.