2010-07-01 5 views
0

Je suis en train d'écrire un plugin dll pour une application. Les charges d'application du plugin ensembles via:XMLSerializer ne peut pas enregistrer/charger lorsqu'il est appelé à partir d'un assembly chargé dynamiquement à partir de l'application parente?

assembly = Assembly.Load(System.IO.File.ReadAllBytes(filename)); 

Le problème se manifeste lorsque je tente de linéariser/désérialiser une classe plublic. Je l'ai réduit à la sérialisation de:

public BindingList<MyClass> MyClasses 
    { get; set; } 

Si je le commente, pas de problèmes. Si je tente de sérialisation avec:

 public static void SaveSettingsFile() 
     { 
      try 
      { 
       XmlSerializer ser = new XmlSerializer(typeof(GameTimeSettings)); 

       TextWriter writer = new StreamWriter(SettingPath); 
       ser.Serialize(writer, Settings.Instance); 
       writer.Close(); 
      } 
      catch (Exception e) 
      { 
       Logger.ReportException("SaveSettingsFile", e); 
       Logger.ReportException("SaveSettingsFile->InnerException", e.InnerException); 
      } 
     } 

Une exception est levée sur ser.Serialize (écrivain, Settings.Instance):

System.InvalidOperationException Msg=There is an error in XML document (0,, 0). -> 
InnerException: Object reference not set to an instance of an object. 

Ma classe a un défaut, constructeur vide. J'ai essayé d'utiliser sgen. Dans une simple application de banc d'essai que j'ai écrite, la sérialisation fonctionne bien ... c'est seulement quand l'assemblage est chargé dynamiquement qu'il y a faute.

En outre, à partir de ces deux fils,

http://forums.gbpvr.com/showthread.php?30384-XMLSerializer-Problems-with-Plugins, http://forums.gbpvr.com/showthread.php?32197-System.XML-Deserialization

Je sais que je peux changer le type de BindingList à ArrayList et le faire fonctionner; cependant, je voudrais garder la liaison de données fonctionnante car il y a beaucoup de paramètres à gérer.

Toute entrée serait appréciée.

+0

Avez-vous déjà initialisé 'MyClasses'? Sinon, sa valeur est "null". –

+0

J'initialise la classe. Comme je l'ai dit, "Dans une application de test simple que j'ai écrit, la sérialisation fonctionne bien ..." –

Répondre

0

Le commentaire de John Saunders semble correct pour ceci jusqu'à présent, vous n'initialisez probablement pas MyClasses. Puisque vous dites que ça fonctionne bien avec SGen, vous pouvez aussi vérifier s'il a quelque chose à voir avec les drapeaux de compilation, comme peut-être essayer de le mettre à jour et de voir si cela change les choses.

+0

SGen ne fonctionnait pas. –

+0

Pouvez-vous poster plus de votre code, y compris l'initialisation de GameTypeSettings ainsi que le constructeur pour MyClass? –

0

Désolé de sortir de la tombe, mais j'ai encore rencontré un problème similaire aujourd'hui et c'était le premier résultat google, alors j'ai pensé que je partagerais.

Cela semble être un cas générique d'un problème que j'avais rencontré il y a un certain temps lorsque j'essayais d'écrire une tâche MSBuild Custom (essentiellement un plugin). J'ai posté à ce sujet sur le MSDN Forums.

Voici la partie la plus pertinente du commentaire, simplement remplacer MSBuild pour toute application qui a une architecture de plug-in, et la bibliothèque CruiseControl.NET pour toute bibliothèque qui utilise le XmlSerializer:

La bibliothèque en question est la bibliothèque Remoting pour CruiseControl.NET de ThoughtWork, cette bibliothèque utilise .NET Remoting avec certains objets activés par le client. Lorsque vous tentez d'activer l'objet, Binary Serializer de .NET se met au travail en essayant de comprendre où charger l'assemblage ThoughtWorks.CruiseControl afin qu'il puisse lire l'objet (ThoughtWorks.CruiseControl.Remote.dll dans 1.4.4SP1 que nous utilisez) le problème est que GetAssembly Logic de Binary Serializer ne réalise pas que MSBuild a effectué du vaudou pour charger l'assembly personnalisé à partir d'un emplacement arbitraire.Par conséquent, il est par défaut d'essayer de regarder dans le même répertoire que le programme est situé dans http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=VS.100%29.aspx ce qui signifie que s'il ne l'a pas trouvé dans le GAC, il va commencer à sonder d'où le programme a été lancé, et MSBuild a été lancé à partir du dossier% FrameworkDir% /% FrameworkVersion% il est peu probable de trouver l'assembly qu'il recherche.

Cela explique pourquoi vous ne voyez pas ce problème dans une application de la console (l'ensemble le plus probable assis juste à côté de l'application de la console)

La solution proposée dans le post Forum MSDN est également applicable ici, essentiellement ils ont ajouté un gestionnaire d'événements supplémentaire pour tenter de sonder à partir d'un emplacement connu, encore une fois je viens de citer les parties pertinentes:

pour toute personne qui prend soin, la solution consiste à enregistrer un gestionnaire pour l'événement AppDomain.AssemblyResolve et à l'Assembly.LoadFrom() là.

Personnellement cela me fait peur, mais il est la seule solution que j'ai trouvé qui fonctionne, un peu plus googler ne m'a pas montré un problème Microsoft Connect pour cela, mais il est le plus susceptible de ne pas être fixe ou est par conception.

Questions connexes