Qual è il modo migliore per deserializzare generici scritti con una versione diversa di un firmato montaggio?

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

Domanda

In altri casi è stato suggerito che è sufficiente aggiungere un SerializationBinder che rimuove la versione dal tipo di montaggio. Tuttavia, quando si utilizza collezioni generici di un tipo trovato in una firma di assemblaggio, che tipo è strettamente con versione basata sul suo assemblaggio.

Ecco quello che ho trovato lavori.

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

Tuttavia, causando il processo di associazione a livello globale cambiamento sembra piuttosto pericoloso per me. Strane cose potrebbero accadere se la serializzazione stava accadendo in più thread. Forse una soluzione migliore è quella di fare un po 'di manipolazione regex del typeName?

Modifica metodo basato La stringa non funziona. Generics a quanto pare hanno bisogno di un pieno di tipo fortemente nome. Piuttosto atroce se mi chiedete.

È stato utile?

Soluzione

L'evento AssemblyResolve viene generato solo se fallisce regolare vincolante. Quindi, tutto ciò che può essere risolto con i metodi normali sarà. Solo operazioni di deserializzazione non sono suscettibili di generare l'evento, e hai una strategia perfettamente valido per cercare di risolvere tali.

mi piacerebbe aggiungere il gestore di eventi AssemblyResolve quando il programma si avvia e lasciarlo lì, piuttosto che l'aggiunta e la rimozione. Che rimuove una potenziale fonte di problemi di multi-threading.

Altri suggerimenti

Invece di serializzare l'intera collezione, si potrebbe iterare attraverso di essa e serializzare ogni elemento singolarmente? Quindi è possibile utilizzare l'approccio SerilizationBinder.

Questo dovrebbe rispondere alla tua domanda: SerializationBinder con List

Quando si utilizza tipi generici nella SerializationBinder.BindToType, è necessario utilizzare nomi di tipo deboli al posto dei nomi di tipo completo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top