Каков наилучший способ десериализовать дженерики, написанные с другой версией подписанной сборки?
-
24-09-2019 - |
Вопрос
В других случаях было предложено, чтобы вы просто добавили сериализацию, который удаляет версию из типа сборки. Однако при использовании общих коллекций типа, найденного в подписанной сборке, этот тип строго версится на основе его сборки.
Вот то, что я нашел, работает.
internal class WeaklyNamedAppDomainAssemblyBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
ResolveEventHandler handler = new ResolveEventHandler(CurrentDomain_AssemblyResolve);
AppDomain.CurrentDomain.AssemblyResolve += handler;
Type returnedType;
try
{
AssemblyName asmName = new AssemblyName(assemblyName);
var assembly = Assembly.Load(asmName);
returnedType = assembly.GetType(typeName);
}
catch
{
returnedType = null;
}
finally
{
AppDomain.CurrentDomain.AssemblyResolve -= handler;
}
return returnedType;
}
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string truncatedAssemblyName = args.Name.Split(',')[0];
Assembly assembly = Assembly.Load(truncatedAssemblyName);
return assembly;
}
}
Однако, вызывая процесс связывания, чтобы изменить глобально, кажется мне довольно опасным. Странные вещи могут произойти, если сериализация происходит в нескольких потоках. Возможно, лучшее решение состоит в том, чтобы сделать некоторые манипулирования на регелевом выражении типенама?
Редактировать: Струнный метод не работает. Дженерики, по-видимому, нуждаются в полном сильно названном типе. Довольно отвратительно, если вы спросите меня.
Решение
Событие AssumblyResolvolve выпускается только в случае сбоя регулярного связывания. Итак, все, что можно решить через нормальные методы. Только десериализационные операции, вероятно, будут уволить мероприятие, и у вас есть совершенно действительную стратегию для попытки разрешить их.
Я бы добавил обработчик события MaskLyresolve, когда программа запускается и оставьте ее там, а не добавлять и удалять ее. Это удаляет потенциальный источник многопоточных проблем.
Другие советы
Вместо того, чтобы сериализировать всю коллекцию, не могли бы вы пройти через него и сериализовать каждый элемент индивидуально? Тогда вы можете использовать подход для SerilizonBinder.
Это должно ответить на ваш вопрос: СериализацияБиндер со спискомu003CT>
При использовании универсальных типов в SerializonBinder.bindtotype необходимо использовать имена слабых типов вместо полностью квалифицированных названий типов.