Каков наилучший способ десериализовать дженерики, написанные с другой версией подписанной сборки?

StackOverflow https://stackoverflow.com/questions/2579353

Вопрос

В других случаях было предложено, чтобы вы просто добавили сериализацию, который удаляет версию из типа сборки. Однако при использовании общих коллекций типа, найденного в подписанной сборке, этот тип строго версится на основе его сборки.

Вот то, что я нашел, работает.

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 необходимо использовать имена слабых типов вместо полностью квалифицированных названий типов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top