在不使用XmlInclude的情况下进行序列化

12
我正在使用 .NET Serialization 反序列化一个名叫 Method 的类。该类包含实现 IAction 接口的对象列表。我最初使用了 [XmlInclude] 属性来指定所有实现 IAction 接口的类。
但现在,我想改变我的程序以加载目录中的所有dll,并剔除实现IAction接口的类。然后用户可以反序列化包含其实现IAction的文件。
我不再控制实现IAction接口的类,因此无法使用[XmlInclude]
有没有一种方式在运行时设置此属性?或者设置实现类的类似属性?
public class Method
{
    public List<Actions.IAction> Actions = new List<Actions.IAction>();
}

public interface IAction
{
    void DoExecute();
}

public static Type[] LoadActionPlugins(string pluginDirectoryPath)
{
    List<Type> pluginTypes = new List<Type>();

    string[] filesInDirectory = Directory.GetFiles(pluginDirectoryPath, "*.dll", SearchOption.TopDirectoryOnly);
    foreach (string pluginPath in filesInDirectory)
    {
        System.Reflection.Assembly actionPlugin = System.Reflection.Assembly.LoadFrom(pluginPath);
        Type[] assemblyTypes = actionPlugin.GetTypes();
        foreach (Type type in assemblyTypes)
        {
            Type foundInterface = type.GetInterface("IAction");
            if (foundInterface != null)
            {
                pluginTypes.Add(type);
            }
        }
    }

    return pluginTypes.Count == 0 ? null : pluginTypes.ToArray();
}
2个回答

10

XmlSerializer有一个构造函数,可以接受一个类型数组,用于在反序列化时识别这些类型:

public XmlSerializer(
   Type type,
   Type[] extraTypes
);

你应该可以将你的assemblyTypes数组作为第二个参数传入。


6
你可以像David Norman所展示的那样将类型数组传递给Xml Serializer。非常需要注意的是,每次这样做都会构建和编译一个新的xml序列化程序。如果你经常这样做,你将面临巨大的内存泄漏和性能问题。
这是一个巨大的内存和性能问题,请确保只做一次。你可以通过缓存你的xml Serializer来解决这个问题: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx MSDN中的片段:
动态生成程序集 为了提高性能,XML序列化基础设施会动态生成程序集以对指定类型进行序列化和反序列化。该基础设施会查找并重用这些程序集。仅在使用以下构造函数时才会出现此行为: XmlSerializer..::.XmlSerializer(Type) XmlSerializer..::.XmlSerializer(Type, String) 如果您使用其他任何构造函数,则会生成多个版本的相同程序集,并且永远不会卸载,这会导致内存泄漏和性能下降。最简单的解决方案是使用前面提到的两个构造函数之一。否则,您必须将程序集缓存到Hashtable中,如下例所示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接