Я бы предпочел сразу извлечь все свои пользовательские типы и использовать их во время сериализации/десериализации. После прочтения этого сообщения мне потребовалось некоторое время, чтобы понять, куда вставить этот список типов, чтобы он был полезен для объекта сериализатора. Ответ был очень прост: этот список нужно использовать как один из входных аргументов конструктора объекта-сериализатора.
1- Я использую два статических универсальных метода для сериализации и десериализации, это может быть более или менее так, как другие выполняют эту работу, или, по крайней мере, это очень ясно для сравнения с вашим кодом:
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- Обратите внимание на конструктор DataContractSerializer. У нас есть второй аргумент, который является точкой входа для внедрения ваших известных типов в объект сериализатора.
3- Я использую статический метод для извлечения всех моих собственных определенных типов из моих собственных сборок. ваш код для этого статического метода может выглядеть так:
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;
}
Поскольку я не занимался WCF (мне нужна была только бинарная сериализация для работы с файлами), мое решение может не совсем соответствовать архитектуре WCF, но откуда-то должен быть доступ к конструктору объекта сериализатора.
person
Alireza Ahmadi Rad
schedule
25.11.2016