XMLSerializer failing save/load when called from an assembly dynamically loaded from parent application?
I am writing a plugin dll for an application. The application loads plugin assemblies via:
assembly = Assembly.Load(System.IO.File.ReadAllBytes(filename));
The problem manifests 开发者_运维技巧itself when I attempt to serialize/deserialize a plublic class. I narrowed it down to the serialization of:
public BindingList<MyClass> MyClasses
{ get; set; }
If I comment this out, no problems. If I attempt to serialize with:
public static void SaveSettingsFile()
{
try
{
XmlSerializer ser = new XmlSerializer(typeof(GameTimeSettings));
TextWriter writer = new StreamWriter(SettingPath);
ser.Serialize(writer, Settings.Instance);
writer.Close();
}
catch (Exception e)
{
Logger.ReportException("SaveSettingsFile", e);
Logger.ReportException("SaveSettingsFile->InnerException", e.InnerException);
}
}
An exception is thrown on ser.Serialize(writer, Settings.Instance) :
System.InvalidOperationException Msg=There is an error in XML document (0,, 0). ->
InnerException: Object reference not set to an instance of an object.
My class has a default, empty constructor. I have tried using sgen. In a simple testbed application I wrote, serialization works fine... it's only when the Assembly is dynamically loaded does it fault.
Furthermore, from these two threads,
http://forums.gbpvr.com/showthread.php?30384-XMLSerializer-Problems-with-Plugins , http://forums.gbpvr.com/showthread.php?32197-System.XML-Deserialization
I know I can change the type from BindingList to ArrayList and have it work; however, I would like to keep databinding working as there are quite a bit of settings to manage.
Any input would be appreciated.
John Saunders' comment appears correct for this so far, you likely are not initializing MyClasses
.
Since you say it works fine with SGen, you might also want to check if it has something to do with the compile flags, like maybe try setting it to release and see if that changes things.
Sorry to pull this up from the grave, but I ran into a similar issue again today and this was the first google result, so I thought I'd share.
This appears to be a generic case of an issue I had ran into awhile back when attempting to write an MSBuild Custom task (basically a plugin). I posted about it on the MSDN Forums.
Here is the most relevant part of the comment, simply substitute MSBuild for any application that has a plugin architecture, and the CruiseControl.NET library for any library that uses the XmlSerializer:
The Library in question is the Remoting Library for ThoughtWork's CruiseControl.NET, this library uses .NET Remoting with some Client Activated Objects. When you go to attempt to activate the object, .NET's Binary Serializer goes to work trying to figure out where to load the ThoughtWorks.CruiseControl assembly from so it can read the object (ThoughtWorks.CruiseControl.Remote.dll in 1.4.4SP1 which we're using) the problem is the Binary Serializer's GetAssembly Logic doesn't realize that MSBuild has performed some voodoo to load the custom assembly from an arbitrary location.
Therefore it defaults to attempting to look in the same directory that the program is located in as per http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=VS.100%29.aspx which means if it didn't find it in the GAC its going to start probing from where the program was launched, and because MSBuild was launched from the %FrameworkDir%/%FrameworkVersion% folder it is unlikely to find the assembly it's looking for.
This explains why you wouldn't see this issue in a console application (the assembly most likely sat right next to the console app)
The solution offered in the MSDN Forum post is also applicable here, basically they added an additional event handler to attempt to probe from a known location, again I have quoted the relevant portions:
For anyone who cares, the workaround is to register a handler for the AppDomain.AssemblyResolve event, and to the Assembly.LoadFrom() there.
Personally this scares me, but it is the only solution I have found that works, a bit more googling hasn't shown me a Microsoft Connect issue for this, but it is most likely not going to be fixed or is by design.
精彩评论