0

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

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

当我尝试序列化/反序列化一个公共类时,问题就显现出来了。我把它缩小到序列化:

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-Plugins , http://forums.gbpvr.com/showthread.php?32197-System.XML-Deserialization

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

任何输入将不胜感激。

4

2 回答 2

0

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

既然您说它可以与 SGen 一起正常工作,您可能还想检查它是否与编译标志有关,比如尝试将其设置为 release 并查看是否会改变。

于 2010-07-01T19:57:41.803 回答
0

很抱歉把这个从坟墓里拿出来,但我今天又遇到了一个类似的问题,这是第一个谷歌结果,所以我想我会分享。

这似乎是我在尝试编写 MSBuild 自定义任务(基本上是一个插件)时遇到的一个问题的一般案例。我在MSDN 论坛上发布了有关它的信息。

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

有问题的库是 ThoughtWork 的 CruiseControl.NET 的远程处理库,该库使用带有一些客户端激活对象的 .NET 远程处理。当您尝试激活对象时,.NET 的二进制序列化程序开始工作,试图找出从哪里加载 ThoughtWorks.CruiseControl 程序集,以便它可以读取对象(我们在 1.4.4SP1 中的 ThoughtWorks.CruiseControl.Remote.dll '正在使用)问题是二进制序列化程序的 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 问题,但它很可能不会被修复或者是设计使然。

于 2012-06-06T19:10:53.163 回答