为什么XmlSerializer.Deserialize抛出System.IO.FileLoadException?

时间:2010-09-26 22:35:47

标签: c# xml-serialization

我遇到了令人困惑的XML反序列化问题。

我正在构建一个支持本地自定义其使用的各种服务的应用程序。我已经实现了一个抽象的ServiceLocator类,其方法返回各种对象。每个自定义安装都负责实现此类的子类并提供这些方法的实现。这堂课的内容如下:

public abstract class ServiceLocator
{
    public static void Initialize(string customFeaturesPath)
    {
        Assembly a = Assembly.LoadFrom(customFeaturesPath);
        Type t = a.GetExportedTypes()
            .AsEnumerable()
            .Where(x => x.IsSubclassOf(typeof (ServiceLocator)))
            .First();
        Default = (ServiceLocator)a.CreateInstance(t.FullName);
    }

    public static ServiceLocator Default { get; private set; }

    public abstract DefaultValuesContainer CreateDefaultValuesContainer();
}

这很好用:我从应用程序配置文件中获取自定义功能部件的路径,程序调用{​​{1}},然后应用程序可以调用Initialize上的各种方法并返回适当的自定义服务实现。

其中一项服务是ServiceLocator.Default。这是一个简单的对象,它公开了需要在用户设置文件中保存其值的属性。我的想法是,我可以将此对象序列化为DefaultValuesContainer类型的单个用户设置。它使用户设置文件你不想手动编辑,但我很酷。

以下是string的具体实现:

ServiceLocator.CreateDefaultValuesContainer

现在就是这样。

我使用NUnit为此构建了单元测试。当我在测试夹具类中运行测试来运行客户端自定义功能时,它们可以工作。当我运行整个测试套件时,上面方法的最后一行抛出了这个异常:

protected override DefaultValuesContainer CreateDefaultValuesContainer(string serializedXml)
{
    DefaultValuesContainer c = new ClientDefaultValuesContainer();

    if (string.IsNullOrEmpty(serializedXml))
    {
        return c;
    }
    XmlSerializer x = new XmlSerializer(c.GetType());
    return (DefaultValuesContainer) x.Deserialize(new StringReader(serializedXml));
}

我有点困惑为什么。 System.InvalidOperationException : There is an error in XML document (0, 0). ----> System.IO.FileLoadException : Could not load file or assembly 'ClientCustomFeatures, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER)) ----> System.ArgumentNullException : Value cannot be null. Parameter name: path1 方法仍然运行,SetUp仍然返回ServiceLocator.Default类型的对象,这意味着它已加载ClientServiceLocator程序集。实际上,抛出异常的方法是在我被告知的程序集中无法加载。

ClientCustomFeatures试图在这做什么?为什么要加载已经加载的程序集? “无效指针”的含义是什么意思?最重要的是,我应该如何调试这样的东西?

4 个答案:

答案 0 :(得分:1)

如果您的自定义程序集不知道在何处加载包含ClientCustomFeatures类的程序集,则会发生这种情况。当您将自定义程序集部署到不在主程序集路径中且主程序集不在gac中的位置时,会发生这种情况。因此,如果从主程序集的子目录加载自定义程序集,则应该消失。但是,如果它们位于任意位置,则会出现问题,因为它们需要加载主程序集,因为它们需要访问ClientCustomFeatures类型。

答案 1 :(得分:0)

当一个程序集加载另一个本身具有(非GAC)引用的程序集时,我遇到了程序集加载程序(Fusion?)的问题。 YourDLL.XmlSerializers.dll可能是一个这样的集会。尝试关闭Visual Studio的选项以自动生成XML序列化程序集(项目选项) - 这将删除其他程序集(因此也依赖于它)。

答案 2 :(得分:0)

Fusion Log Viewer

为了帮助诊断这些装配加载问题,请查看Fusion Log Viewer(AKA fuslogvw.exe)。

Fusion ==定位和加载程序集的.NET组件。

答案 3 :(得分:0)

尝试替换该行:

XmlSerializer x = new XmlSerializer(c.GetType()); 

使用:

XmlSerializer x = new XmlSerializer(c.GetType(), new Type[] { typeof(DefaultValuesContainer), typeof(ClientDefaultValuesContainer) });