C # Xml Serialization: cannot (de) serialize an object that comes from another assembly

I am trying to XML serialize / deserialize an object in C #. The catch is that this object is of a type that was not declared in the same assembly as the code causing the serialization. Instead, it comes from an assembly loaded dynamically at runtime, ant, so at compile time it is not known the code that causes serialization.

The type I'm trying to serialize is as follows:

//Assembly = P.dll namespace EDFPlugin.Plugin1 { [Serializable] [XmlRoot(Namespace = "EDFPlugin.Plugin1")] [XmlInclude(typeof(Options))] public class Options { private string _username; private string _password; public string Username { get { return _username; } set { _username = value;} } public string Password { get { return _password; } set { _password = value; } } } } 

As I mentioned earlier, the code that I use to try to serialize / deserialize this object is in an assembly that is not aware of the Options type at compile time (since it dynamically loads P.dll at run time). However, I managed to serialize the type correctly using this code:

 //Assembly = A.exe (doesn't know about P.dll at compile time) object value = GetOptions() //the actual type returned by this method is EDFPlugin.Plugin1.Options !! XmlSerializer valueSerializer = new XmlSerializer(value.GetType()); valueSerializer.Serialize(writer, value); 

basically, as you can see, by calling GetType() , I can get around the problem of the lack of knowledge like Options at compile time, everything works fine.

The problem occurs when trying to deserialize:

 //Assembly = A.exe (doesn't know about P.dll at compile time) XmlSerializer valueSerializer = new XmlSerializer(typeof(object)); //have to use object, as I don't know the type in question... object value = valueSerializer.Deserialize(reader); //throws exception 

Since I don’t know the predefined type, I basically can’t properly configure the XmlSerializer . Using a generic object , as shown in the code above, throws an exception:

 "<Options xmlns='EDFPlugin.Plugin1'> was not expected." 

How can i solve this?

+5
source share
1 answer

A.exe (does not know about P.dll at compile time)

So, if A.exe knows this at runtime, you can dynamically load EDFPlugin.Plugin1

What about:

 XmlSerializer valueSerializer = new XmlSerializer(Type.GetType("EDFPlugin.Plugin1.Options")); object value = valueSerializer.Deserialize(reader); 

But what if I don't know that name either?

It is recommended that you put the user interface in order to distinguish the option class from another class, then you can dynamically filter and load it using the XmlSerializer.

 public interface IAmPlugin { } public class Options: IAmPlugin { ...... } 

Then:

 Assembly assembly = ... // Your Assemblie which contains plugin // XmlSerializer needs all possible types to Deserialize an interface var possibleTypes = assembly.GetTypes().Where(t => t.IsClass && t.IsAssignableFrom(typeof(IAmPlugin))).ToArray(); XmlSerializer serializer = new XmlSerializer(typeof(IAmPlugin), possibleTypes); object value = valueSerializer.Deserialize(reader); 

It is assumed that you have empty public constructors of the Options class.

Why an interface instead of an attribute? Because XmlSerializer only handles a few interface types.

+3
source

Source: https://habr.com/ru/post/1236907/


All Articles