4

その他の場合は、アセンブリタイプからバージョンを削除するSerializationBinderを追加することをお勧めします。ただし、署名されたアセンブリで見つかったタイプのジェネリックコレクションを使用する場合、そのタイプはそのアセンブリに基づいて厳密にバージョン管理されます。

これが私が見つけた作品です。

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

ただし、バインディングプロセスをグローバルに変更させることは、私にはかなり危険に思えます。複数のスレッドでシリアル化が行われていると、奇妙なことが起こる可能性があります。おそらく、より良い解決策は、typeNameの正規表現操作を行うことです。

編集: 文字列ベースの方法は機能しません。ジェネリックスには、完全に厳密に名前が付けられた型が必要なようです。あなたが私に尋ねればかなり凶悪です。

4

3 に答える 3

2

AssemblyResolveイベントは、通常のバインディングが失敗した場合にのみ発生します。したがって、通常の方法で解決できるものはすべてです。逆シリアル化操作のみがイベントを発生させる可能性があり、それらを解決しようとするための完全に有効な戦略があります。

プログラムの起動時にAssemblyResolveイベントハンドラーを追加して、追加および削除するのではなく、そのままにしておきます。これにより、マルチスレッドの問題の潜在的な原因が取り除かれます。

于 2010-04-05T16:38:43.643 に答える
0

これはあなたの質問に答えるはずです:List<T>を使用したSerializationBinder

SerializationBinder.BindToTypeでジェネリック型を使用する場合は、完全修飾型名ではなく、弱い型名を使用する必要があります。

于 2011-11-04T20:24:03.250 に答える
0

コレクション全体をシリアル化するのではなく、コレクション全体を反復処理して、各要素を個別にシリアル化できますか?次に、SerilizationBinderアプローチを使用できます。

于 2010-04-05T16:27:38.007 に答える