Quelle est la meilleure façon de désérialiser génériques écrits avec une version différente d'un assemblage signé?

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

Question

Dans d'autres cas, il a été suggéré que vous ajoutez simplement une SerializationBinder qui supprime la version du type de montage. Cependant, lors de l'utilisation des collections génériques d'un type trouvé dans un ensemble signé, ce type est strictement Versioned en fonction de son assemblage.

Voici ce que j'ai oeuvres trouvées.

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;
    }
}

Cependant, ce qui provoque le processus de liaison au changement semble globalement assez dangereux pour moi. Des choses étranges peuvent se produire si sérialisation se passait dans plusieurs threads. Peut-être une meilleure solution est de faire une manipulation regex du typeName?

Modifier La chaîne méthode basée ne fonctionne pas. Génériques apparemment besoin d'un type plein un nom fort. Tout à fait odieux si vous me demandez.

Était-ce utile?

La solution

L'événement AssemblyResolve est tiré seulement en cas d'échec régulier de liaison. Donc, tout ce qui peut être résolu par des méthodes normales sera. Seules les opérations de désérialisation sont susceptibles de déclencher l'événement, et vous avez une stratégie parfaitement valable pour essayer de les résoudre.

Je rajouterais le gestionnaire d'événements AssemblyResolve lorsque le programme démarre et laisse là, plutôt que d'ajouter et de supprimer. Cela supprime une source potentielle de problèmes multi-threading.

Autres conseils

Au lieu de sérialisation toute la collection, pourriez-vous itérer et sérialiser chaque élément individuellement? Ensuite, vous pouvez utiliser l'approche SerilizationBinder.

Cela devrait répondre à votre question: SerializationBinder avec Liste

Lors de l'utilisation des types génériques dans le SerializationBinder.BindToType, vous devez utiliser les noms de type faibles au lieu des noms de type qualifié.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top