Comment sérialiser/désérialiser un objet chargé d'une autre assemblée?
Je veux sérialiser/désérialiser un objet qui a été instancié par un autre objet chargé à partir d'un assemblage:
Interfaces.cs (à partir d'un assemblage, Interfaces.dll)
public interface ISomeInterface
{
ISettings Settings { get; set; }
}
public interface ISettings : ISerializable
{
DateTime StartDate { get; }
}
SomeClass.cs (à partir d'un assemblage, SomeClass.dll)
public class SomeClass : ISomeInterface
{
private MySettings settings = new Settings();
public ISettings Settings
{
get { return (ISettings)settings; }
set { settings = value as MySettings; }
}
}
[Serializable]
public class MySettings : ISettings
{
private DateTime dt;
public MySettings() { dt = DateTime.Now; }
protected MySettings(SerializationInfo info, StreamingContext context)
{
dt = info.GetDateTime("dt");
}
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("dt", dt);
}
public DateTime StartDate
{
get { return startFrom; }
internal set { startFrom = value; }
}
}
De démarrage du projet:
[Serializable]
public class ProgramState
}
public ISettings Settings { get; set; }
}
Dans le projet de démarrage, finalement, j'ai réglé les Paramètres d'une instance de ProgramState de Paramètres de SomeClass. Je puis aller faire de la sérialisation à l'aide:
public void SerializeState(string filename, ProgramState ps)
{
Stream s = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(s, ps);
s.Close();
}
Ce n'est pas de jeter des exceptions. Je désérialiser avec:
public ProgramState DeserializeState(string filename)
{
if (File.Exists(filename))
{
ProgramState res = new ProgramState();
Stream s = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
try
{
res = (ProgramState)bFormatter.Deserialize(s);
}
catch (SerializationException se)
{
Debug.WriteLine(se.Message);
}
s.Close();
return res;
}
else return new ProgramState();
}
Cela déclenche une exception et le message suivant apparaît à ma sortie de Débogage:
Une exception de première chance de type 'System.Moment de l'exécution.La sérialisation.SerializationException' s'est produite dans mscorlib.dll
Impossible de trouver l'assembly 'SomeClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null".
Je suis sûr que l'assemblée contenant SomeClass a été chargé avant l'appel à DeserializeState, alors pourquoi est-il en levant une exception qu'il est incapable de le trouver?
J'ai été en regardant des tutoriels, mais ceux que j'ai pu trouver ne traite qu'avec des classes à partir de la même assemblée (et en plus, ma compréhension de la sérialisation et de désérialisation processus .NET est minime - un lien vers une explication détaillée peut être utile).
Dans l'intervalle, est-il possible de faire cela correctement désérialiser le MySettings objet?
J'ai couru le code que vous avez posté et tout fonctionne bien. Il me semble que le code serait pause avant de désérialisation si SomeClass.dll n'a pas été chargé. Sont tous les projets ciblant les mêmes .NET framework version?
merci je vais regarder.
Oui, l'application doit être compatible avec .NET Framework 3.5 et tous les projets sont définis pour cette version. Je suis à l'aide d'un Système.ComponentModel.Composition pour charger les assemblées et tous les projets (à l'exception des Interfaces de la bibliothèque qui n'en a pas besoin) d'inclure une référence au même fichier DLL qui définit l'espace de nom.
OriginalL'auteur Nikola Novak | 2011-11-18
Vous devez vous connecter pour publier un commentaire.
Après avoir farfouillé peu plus (c'est à dire googler la réponse), j'ai été en mesure de résoudre ce problème. Voici le code modifié:
Interfaces.cs (à partir d'un assemblage, Interfaces.dll)
SomeClass.cs (à partir d'un assemblage, SomeClass.dll)
La sérialisation est fait avec:
Et la désérialisation avec:
Cette classe a été ajoutée. C'est le liant pour le binaire formateur:
Vous avez sauvé ma journée!
OriginalL'auteur Nikola Novak
Vous souhaitez (de)sérialiser en utilisant le format binaire?
Si aucune vous pouvez utiliser les éléments suivants:
P. S. Ce n'est pas une solution mais une sorte de solution de contournement.
Certains assemblée
interface publique ISomeInterface
{
ISettings Paramètres { get; set; }
}
Certains autres de l'assemblée
OriginalL'auteur VMykyt