2008-12-16 15 views
12

Ich deserialisiere eine Klasse namens Method mit .NET Serialisierung. Method enthält eine Liste von Objekten, die IAction implementieren. Ich habe ursprünglich das Attribut [XmlInclude] verwendet, um alle Klassen anzugeben, die IAction implementieren.Serialisierung ohne XmlInclude

Aber jetzt möchte ich mein Programm ändern, um alle DLLs in einem Verzeichnis zu laden und die Klassen zu entfernen, die IAction implementieren. Dann können Benutzer Dateien deserialisieren, die ihre Aktionen enthalten, die IAction implementieren.

Ich kontrolliere nicht die Klassen, die IAction mehr implementieren, daher kann ich [XmlInclude] nicht verwenden.

Gibt es eine Möglichkeit, dieses Attribut zur Laufzeit zu setzen? Oder haben Sie ein ähnliches Attribut für die implementierende Klasse?

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

Antwort

10

XmlSerializer hat einen Konstruktor, der ein Array von Typen akzeptiert, die akzeptiert werden, wenn Deserialisieren:

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

Sie sollten in der Lage sein, Ihr Array von assemblyTypes als zweites Argument übergeben.

6

Sie können eine Reihe von Typen in den Xml Serializer einbinden, wie David Norman gezeigt hat. Ein großes Wort der Vorsicht. Jedes Mal, wenn Sie dies tun, wird ein neuer XML-Serializer erstellt und kompiliert. Wenn Sie dies viel tun, haben Sie ein großes Speicherleck und Performance-Schwindel auf Ihrer Hand.

Dies ist ein großer Speicher und Leistung Schwein, stellen Sie sicher, dass Sie dies nur einmal tun. Sie können dies beheben, indem Sie Caching Ihre xml Serializer: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

Snippet von MSDN:

Dynamisch generierte Baugruppen Leistung zu erhöhen, die XML Serialisierung Infrastruktur Baugruppen serialize dynamisch generiert und bestimmte Typen deserialisieren. Die Infrastruktur findet und verwendet diese Baugruppen erneut. Dieses Verhalten tritt nur, wenn die folgenden Konstruktoren mit:

XmlSerializer .. :: XmlSerializer (Type)

XmlSerializer .. :: XmlSerializer (Type, String)

Wenn Sie eines verwenden.. die anderen Konstruktoren, mehrere Versionen der gleichen Baugruppe werden generiert und nie entladen, was zu einem Speicherverlust und schlechte Leistung führt. Die einfachste Lösung besteht darin, einen der zuvor genannten zwei Konstruktoren zu verwenden. Ansonsten müssen Sie die Baugruppen in einer Hashtable zwischen zwischenspeichern, wie im folgenden Beispiel gezeigt .

Verwandte Themen