从从父应用程序动态加载的程序集调用时,XMLSerializer是否失败了保存/加载?

时间:2010-07-01 19:43:05

标签: c# xmlserializer

我正在为应用程序编写一个插件dll。该应用程序通过以下方式加载插件程序集:

assembly = Assembly.Load(System.IO.File.ReadAllBytes(filename)); 

当我尝试序列化/反序列化plublic类时,问题就会出现。我把它缩小到了序列化:

public BindingList<MyClass> MyClasses
    { get; set; }

如果我发表评论,没问题。如果我尝试序列化:

        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);
            }
        }

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.

我的类有一个默认的空构造函数。我尝试过使用sgen。在我写的一个简单的测试平台应用程序中,序列化工作正常......只有在动态加载程序集时它才会出错。

此外,从这两个主题,

http://forums.gbpvr.com/showthread.php?30384-XMLSerializer-Problems-with-Pluginshttp://forums.gbpvr.com/showthread.php?32197-System.XML-Deserialization

我知道我可以将类型从BindingList更改为ArrayList并使其工作;但是,我想保持数据绑定工作,因为有很多设置需要管理。

任何意见都会受到赞赏。

2 个答案:

答案 0 :(得分:0)

到目前为止,John Saunders的评论似乎是正确的,您可能没有初始化MyClasses

既然你说它适用于SGen,你可能还想检查它是否与编译标志有关,比如尝试将其设置为释放并查看是否会改变。

答案 1 :(得分:0)

很抱歉从坟墓中提起这件事,但我今天又遇到了类似的问题,这是谷歌的第一个结果,所以我想我会分享。

这似乎是我在尝试编写MSBuild Custom任务(基本上是一个插件)时遇到的一个问题的一般情况。我在MSDN Forums上发布了它。

以下是评论中最相关的部分,只需将MSBuild替换为任何具有插件架构的应用程序,将CruiseControl.NET库替换为使用XmlSerializer的任何库:

  

有问题的图书馆是ThoughtWork的CruiseControl.NET的远程处理库,该库使用.NET Remoting和一些客户端激活的对象。当你试图激活对象时,.NET的Binary Serializer开始尝试找出从哪里加载ThoughtWorks.CruiseControl程序集,以便它可以读取对象(1.4.4SP1中的ThoughtWorks.CruiseControl.Remote.dll我们“正在使用”问题是Binary Serializer的GetAssembly Logic没有意识到MSBuild已经执行了一些伏都教来从任意位置加载自定义程序集。

     

因此,它默认尝试按http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=VS.100%29.aspx查找程序所在的同一目录,这意味着如果它没有在GAC中找到它,它将开始探测程序的启动位置,并且因为MSBuild是从%FrameworkDir%/%FrameworkVersion%文件夹启动的,所以它不太可能找到它正在寻找的程序集。

     

这解释了为什么您不会在控制台应用程序中看到此问题(该程序集很可能位于控制台应用程序旁边)

MSDN论坛帖子中提供的解决方案也适用于此,基本上他们添加了一个额外的事件处理程序来尝试从已知位置进行探测,我再次引用了相关部分:

  

对于任何关心的人,解决方法是为AppDomain.AssemblyResolve事件注册处理程序,并在那里注册Assembly.LoadFrom()。

就个人而言,这让我感到害怕,但这是我发现的唯一有效的解决方案,更多谷歌搜索没有向我展示Microsoft Connect问题,但它很可能不会被修复或者是设计