wolałbym wyodrębnić moich własnych typów naraz i użyć go podczas serializacji/deserializacji. Po przeczytaniu tego postu zajęło mi trochę czasu, aby zrozumieć, gdzie wprowadzić tę listę typów, aby była użyteczna dla obiektu serializera. Odpowiedź była dość prosta: ta lista ma być używana jako jeden z argumentów wejściowych konstruktora obiektu serializera.
1- używam dwóch statycznych metod generycznych dla serializacji i deserializacji, może to być mniej więcej taki sposób inni też wykonać zadanie, albo przynajmniej jest bardzo jasne dokonywania porównań z kodem:
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- Proszę zwrócić uwagę na konstruktora DataContractSerializer.Mamy tam drugi argument, który jest punktem wyjściowym do wstrzykiwania twoich znanych typów do serializera.
3- Używam statycznej metody wyodrębniania wszystkich własnych zdefiniowanych typów z moich własnych zespołów. Twój kod dla tej metody statycznej może wyglądać następująco:
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;
}
Ponieważ nie był zaangażowany w WCF (I tylko potrzebne binarny serializacji do pracy pliku), moje rozwiązanie może nie dokładnie rozwiązania architektury WCF, ale musi mieć dostęp do konstruktora obiektu serializera skądś.
Jeśli nie chcesz tworzyć metody rozszerzeń, można ją przekształcić w jednolinijkową. 'return Assembly.GetExecutingAssembly(). GetTypes(). Gdzie (_ => _.IsSubclassOf (typeof (TaskBase))) ToArray();' – x5657
To jest świetne rozwiązanie. Czyste i proste. – kenjara
To jest ratownik, dziękuję! –