Sérialisation sans XmlInclude

Je désérialise une classe appelée Method utilisant la sérialisation .NET. Method contient une liste d’objects implémentant IAction . À l’origine, j’avais utilisé l’atsortingbut [XmlInclude] pour spécifier toutes les classes qui implémentaient IAction .

Mais maintenant, je voudrais changer mon programme pour charger toutes les dll dans un répertoire et IAction les classes qui implémentent IAction . Les utilisateurs peuvent ensuite désérialiser les fichiers contenant leurs actions mettant en oeuvre IAction .

Je ne contrôle plus les classes qui implémentent IAction , donc je ne peux pas utiliser [XmlInclude] .

Est-il possible de définir cet atsortingbut au moment de l’exécution? Ou avez-vous un atsortingbut similaire défini pour la classe d’implémentation?

 public class Method { public List Actions = new List(); } public interface IAction { void DoExecute(); } public static Type[] LoadActionPlugins(ssortingng pluginDirectoryPath) { List pluginTypes = new List(); ssortingng[] filesInDirectory = Directory.GetFiles(pluginDirectoryPath, "*.dll", SearchOption.TopDirectoryOnly); foreach (ssortingng 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(); } 

XmlSerializer a un constructeur qui accepte un tableau de types qui seront acceptés lors de la désérialisation:

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

Vous devriez pouvoir passer votre tableau d’assemblyTypes comme deuxième argument.

Vous pouvez avoir un éventail de types dans le sérialiseur XML, comme l’a montré David Norman. Un énorme mot de prudence. Chaque fois que vous faites cela, un nouveau sérialiseur XML est construit et compilé. Si vous faites cela souvent, vous aurez une énorme fuite de mémoire et une performance excessive sur votre main.

Il s’agit d’une mémoire énorme et d’une performance énorme, assurez-vous de ne le faire qu’une fois. Vous pouvez résoudre ce problème en mettant en cache votre sérialiseur XML: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

Extrait de MSDN:

Assemblages générés dynamicment Pour améliorer les performances, l’infrastructure de sérialisation XML génère de manière dynamic des assemblys pour sérialiser et désérialiser les types spécifiés. L’infrastructure trouve et réutilise ces assemblages. Ce problème se produit uniquement lors de l’utilisation des constructeurs suivants:

XmlSerializer .. ::. XmlSerializer (Type)

XmlSerializer .. ::. XmlSerializer (Type, Chaîne)

Si vous utilisez l’un des autres constructeurs, plusieurs versions du même assemblage sont générées et jamais déchargées, ce qui entraîne une fuite de mémoire et des performances médiocres. La solution la plus simple consiste à utiliser l’un des deux constructeurs mentionnés précédemment. Sinon, vous devez mettre en cache les assemblys dans une table de hachage, comme illustré dans l’exemple suivant.