Was ist der beste Weg, Generika mit einer anderen Version einer Baugruppe unterzeichnet geschrieben deserialisieren?

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

Frage

In anderen Fällen wurde vorgeschlagen, dass man einfach eine SerializationBinder hinzuzufügen, die die Version von dem Montagetyp entfernt. Verwendung fand allgemeine Sammlungen eines Typs eines Wenn jedoch in signierte Assembly, wird diese Art streng auf seine Montage auf Basis versioniert.

Hier ist, was ich gefunden habe funktioniert.

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

Allerdings verursacht den Bindungsprozess global zu ändern scheint ziemlich gefährlich für mich. Seltsame Dinge passieren könnte, wenn die Serialisierung in mehreren Threads geschah. Vielleicht eine bessere Lösung ist es, einige regex Manipulation des Typnamen zu tun?

Edit: Der String basierte Methode nicht funktioniert. Generics müssen offenbar eine vollständige stark genannte Art. Ganz abscheulich, wenn Sie mich fragen.

War es hilfreich?

Lösung

Das AssemblyResolve Ereignis wird nur gestartet, wenn regelmäßige Bindung versagt. Also, alles, was über die üblichen Methoden gelöst werden kann, werden. Nur sind Deserialisierungsvorgängen wahrscheinlich das Ereignis ausgelöst, und Sie haben eine absolut gültige Strategie bekommen für den Versuch, diejenigen zu lösen.

Ich würde die AssemblyResolve Event-Handler hinzufügen, wenn das Programm startet und lassen Sie ihn dort, anstatt das Hinzufügen und zu deinstallieren. Das entfernt eine potentielle Quelle für Multi-Threading-Fragen.

Andere Tipps

Anstatt die ganze Kollektion Serialisierung, könnten Sie durchlaufen sie und individuell jedes Element serialisiert? Dann können Sie den SerilizationBinder Ansatz.

Dies sollte Ihre Frage beantworten: SerializationBinder mit List

Wenn generische Typen in der SerializationBinder.BindToType verwenden, müssen Sie Namen schwachen Typs anstelle von voll qualifizierten Typnamen verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top