2008-12-16 28 views
12

我使用.NET序列化反序列化名为Method的类。 Method包含实施IAction的对象列表。我最初使用[XmlInclude]属性来指定实现IAction的所有类。序列化无XmlInclude

但现在,我想改变我的程序加载所有的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(); 
} 

回答

10

XmlSerializer的具有接受的反序列化时将接受类型数组构造函数:

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

你应该能够通过你的assemblyTypes的数组作为第二个参数。

6

您可以像David Norman所示的那样将一个类型数组放入Xml Serializer中。一个巨大的警告字。每当你这样做时,一个新的xml序列化器就被构建和编译。如果你这样做了很多,你将会有巨大的内存泄漏和性能问题。

这是一个巨大的记忆和性能猪,确保你只做一次。从MSDN http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

摘录: 您可以通过缓存XML序列化解决此

动态生成的程序集为了提高性能,在XML序列化 基础设施动态生成组件,以 序列化和反序列化指定类型。基础架构发现 并重新使用这些程序集。使用 下面的构造函数,只有当出现此现象:

的XmlSerializer .. :: XmlSerializer的(类型)

的XmlSerializer .. :: XmlSerializer的(类型,字符串)

如果您使用的。其他构造函数会生成多个版本的 相同程序集并且从不卸载,这会导致内存泄漏和性能下降。最简单的解决方案是使用前面提到的两个构造函数中的一个 。否则,必须将 将程序集缓存在Hashtable中,如以下 示例所示。