Qual è il modo migliore per deserializzare generici scritti con una versione diversa di un firmato montaggio?
-
24-09-2019 - |
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.
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.