代码之家  ›  专栏  ›  技术社区  ›  Rick Minerich

使用不同版本的已签名程序集反序列化泛型的最佳方法是什么?

  •  4
  • Rick Minerich  · 技术社区  · 16 年前

    在其他情况下,建议您只需添加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进行一些regex操作?

    编辑: 基于字符串的方法不起作用。泛型显然需要一个完整的强名称类型。如果你问我的话,真是十恶不赦。

    3 回复  |  直到 14 年前
        1
  •  2
  •   TarkaDaal    16 年前

    仅当常规绑定失败时才会激发AssemblyResolve事件。所以,任何可以通过普通方法解决的问题都是。只有反序列化操作才可能触发事件,并且您有一个完全有效的策略来尝试解决这些问题。

    我会在程序启动时添加AssemblyResolve事件处理程序并将其保留在那里,而不是添加和删除它。这消除了多线程问题的潜在来源。

        2
  •  0
  •   TarkaDaal    16 年前

    与其序列化整个集合,还不如遍历它并分别序列化每个元素?然后可以使用serilizationbinder方法。

        3
  •  0
  •   Community Mohan Dere    9 年前

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

    在serializationbinder.bindtotype中使用泛型类型时,需要使用弱类型名而不是完全限定的类型名。

    推荐文章