[英]What is the best way to deserialize generics written with a different version of a signed assembly?
In other cases it has been suggested that you simply add a SerializationBinder which removes the version from the assembly type. 在其他情况下,建议您仅添加一个SerializationBinder即可从程序集类型中删除该版本。 However, when using generic collections of a type found in a signed assembly, that type is strictly versioned based on its assembly.
但是,当使用在签名程序集中找到的类型的泛型集合时,该类型将严格根据其程序集进行版本控制。
Here is what I've found works. 这是我发现有效的方法。
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;
}
}
However, causing the binding process to change globally seems rather dangerous to me. 但是,使绑定过程全局更改对我来说似乎很危险。 Strange things could happen if serialization was happening in multiple threads.
如果在多个线程中进行序列化,可能会发生奇怪的事情。 Perhaps a better solution is to do some regex manipulation of the typeName?
也许更好的解决方案是对typeName进行一些正则表达式操作?
Edit: The string based method does not work. 编辑:基于字符串的方法不起作用。 Generics apparently need a full strongly named type.
泛型显然需要一个完整的强命名类型。 Quite heinous if you ask me.
如果你问我,那真是令人发指。
The AssemblyResolve event is only fired if regular binding fails. 仅当常规绑定失败时才触发AssemblyResolve事件。 So, anything that can be resolved through normal methods will be.
因此,任何可以通过常规方法解决的问题都将得到解决。 Only deserialization operations are likely to fire the event, and you've got a perfectly valid strategy for trying to resolve those.
只有反序列化操作才有可能触发该事件,并且您有一个完全有效的策略来尝试解决这些问题。
I'd add the AssemblyResolve event handler when the program starts up and leave it there, rather than adding and removing it. 我会在程序启动时添加AssemblyResolve事件处理程序,然后将其保留在那里,而不是添加和删除它。 That removes a potential source of multi-threading issues.
这消除了潜在的多线程问题。
Rather than serializing the whole collection, could you iterate through it and serialize each element individually? 您是否可以序列化整个集合并分别序列化每个元素,而不是序列化整个集合? Then you can use the SerilizationBinder approach.
然后,您可以使用SerilizationBinder方法。
This should answer your question: SerializationBinder with List<T> 这应该可以回答您的问题: 具有List <T>的SerializationBinder
When using generic types in the SerializationBinder.BindToType, you need to use weak type names instead of fully qualified type names. 在SerializationBinder.BindToType中使用泛型类型时,您需要使用弱类型名称而不是完全限定类型名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.