¿Cuál es la mejor manera de deserializar genéricos escritos con una versión diferente de un montaje firmado?

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

Pregunta

En otros casos se ha sugerido que sólo tiene que añadir un SerializationBinder que elimina la versión del tipo de montaje. Sin embargo, cuando se utiliza colecciones genéricas de un tipo que se encuentra en un montaje firmado, ese tipo se versiona basa estrictamente en su montaje.

Esto es lo que he encontrado obras.

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

Sin embargo, haciendo que el proceso de enlace con el cambio global parece bastante peligroso para mí. cosas extrañas pueden suceder si la serialización estaba ocurriendo en varios subprocesos. Tal vez una mejor solución es hacer una cierta manipulación de expresiones regulares de la typeName?

Editar método basado en la cadena no funciona. Los genéricos aparentemente necesitan un tipo con nombre seguro completo. Bastante atroz si me preguntas.

¿Fue útil?

Solución

El evento AssemblyResolve sólo se disparó si falla la unión regular. Por lo tanto, cualquier cosa que pueda ser resuelto a través de métodos normales será. Sólo operaciones de deserialización son propensos a desencadenar el evento, y usted tiene una estrategia perfectamente válida para tratar de resolver esos.

Yo añadiría el controlador de eventos AssemblyResolve cuando el programa se pone en marcha y dejarlo allí, en lugar de añadir y retirar la misma. Que elimina una fuente potencial de problemas multi-threading.

Otros consejos

En lugar de la serialización de toda la colección, se puede iterar a través de él y serializar cada elemento de forma individual? A continuación, puede utilizar el enfoque SerilizationBinder.

Esto debe responder a su pregunta: SerializationBinder con la lista

Cuando se utilizan los tipos genéricos en el SerializationBinder.BindToType, es necesario utilizar nombres de tipos débiles en lugar de nombres de tipo completo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top