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

这应该回答你的问题:SerializationBinder with List<T>

在 SerializationBinder.BindToType 中使用泛型类型时,您需要使用弱类型名称而不是完全限定类型名称。

于 2011-11-04T20:24:03.250 回答
0

您可以遍历它并单独序列化每个元素,而不是序列化整个集合吗?然后你可以使用 SerilizationBinder 方法。

于 2010-04-05T16:27:38.007 回答