Ich würde eher auf einmal meine benutzerdefinierte Typen extrahieren und sie während der Serialisierung/Deserialisierung verwenden. Nachdem ich diesen Beitrag gelesen hatte, brauchte ich eine Weile, um zu verstehen, wo diese Typenliste eingefügt werden sollte, um für das Serializer-Objekt nützlich zu sein. Die Antwort war ziemlich einfach: Diese Liste wird als eines der Eingabeargumente des Konstruktors des Serialisierungsobjekts verwendet.
1- Ich bin zwei statische generische Methoden für die Serialisierung und Deserialisierung verwenden, das mehr oder weniger so, wie andere auch die Arbeit erledigen kann, oder zumindest ist es für die Herstellung Vergleich mit Ihrem Code sehr klar:
public static byte[] Serialize<T>(T obj)
{
var serializer = new DataContractSerializer(typeof(T), MyGlobalObject.ResolveKnownTypes());
var stream = new MemoryStream();
using (var writer =
XmlDictionaryWriter.CreateBinaryWriter(stream))
{
serializer.WriteObject(writer, obj);
}
return stream.ToArray();
}
public static T Deserialize<T>(byte[] data)
{
var serializer = new DataContractSerializer(typeof(T), MyGlobalObject.ResolveKnownTypes());
using (var stream = new MemoryStream(data))
using (var reader =
XmlDictionaryReader.CreateBinaryReader(
stream, XmlDictionaryReaderQuotas.Max))
{
return (T)serializer.ReadObject(reader);
}
}
2- Bitte beachten Sie den Konstruktor von DataContractSerializer.Wir haben dort ein zweites Argument, das den Einstiegspunkt für das Einfügen Ihrer bekannten Typen in das Serializer-Objekt darstellt.
3- Ich verwende eine statische Methode, um alle meine eigenen definierten Typen aus meinen eigenen Baugruppen zu extrahieren.
private static Type[] KnownTypes { get; set; }
public static Type[] ResolveKnownTypes()
{
if (MyGlobalObject.KnownTypes == null)
{
List<Type> t = new List<Type>();
List<AssemblyName> c = System.Reflection.Assembly.GetEntryAssembly().GetReferencedAssemblies().Where(b => b.Name == "DeveloperCode" | b.Name == "Library").ToList();
foreach (AssemblyName n in c)
{
System.Reflection.Assembly a = System.Reflection.Assembly.Load(n);
t.AddRange(a.GetTypes().ToList());
}
MyGlobalObject.KnownTypes = t.ToArray();
}
return IOChannel.KnownTypes;
}
Da ich nicht in WCF beteiligt war (ich brauchte nur eine binäre Serialisierung für Dateioperation) kann meine Lösung nicht genau adressieren die WCF-Architektur, aber es muss: Code für diese statische Methode wie folgt aussehen Zugriff auf den Konstruktor des Serialisierungsobjekts von irgendwo.
Wenn Sie die Erweiterungsmethode nicht erstellen möchten, können Sie diese zu einem Einzeiler machen. 'return Assembly.GetExecutingAssembly(). GetTypes(). Wo (_ => _.IsSubclassOf (typeof (TaskBase))). ToArray();' – x5657
Dies ist eine großartige Lösung. Sauber und einfach. – kenjara
Dies ist ein Lebensretter, danke! –