.Net 同一个程序集的两个版本在一个 AppDomain 中加载时是不是存在潜在问题?

Posted

技术标签:

【中文标题】.Net 同一个程序集的两个版本在一个 AppDomain 中加载时是不是存在潜在问题?【英文标题】:.Net Are there potential problems when two versions of the same assembly are loaded in one AppDomain?.Net 同一个程序集的两个版本在一个 AppDomain 中加载时是否存在潜在问题? 【发布时间】:2010-02-17 15:46:41 【问题描述】:

当两个版本之间发生重大更改时,我们提出了一种处理向后兼容性的策略。我们在当前的 AppDomain 中加载以前版本的程序集,用旧版本类型反序列化一些数据,然后将它们转换为新版本中的等价物。

    我应该注意这种方法是否存在任何缺陷? 如果我在省略其程序集版本时尝试通过反射加载类型会发生什么情况,如果当前 AppDomain 中存在该类型的两个版本,它是否总是加载该类型的最新版本?

编辑:

这是问题#2的一个场景,

这两个程序集加载在同一个 AppDomain 中:

MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089 MyAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089

两个程序集都定义了 MyAssembly.MyType 类型。

那么如果某些代码使用这种反射:

Type t = Type.GetType("MyAssembly.MyType, MyAssembly, Culture=neutral, PublicKeyToken=b17a5c561934e089");

这个调用会确定返回MyAssembly.MyType, MyAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089吗?

我想如果我在反序列化存在于同一程序集的两个加载版本中的类型时使用BinaryFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple,也会发生同样的情况。

【问题讨论】:

【参考方案1】:

我将假设您使用 Assembly.LoadFile()。反射并不能真正让你陷入困境,它需要一个装配参考来让球滚动。您的代码在决定使用哪个程序集引用时处于控制之中。显然,如果您想从旧版本加载类型,您将需要之前调用 LoadFile() 获得的那个。

LoadFile() 调用不能以其他方式破坏任何其他程序集解析,程序集在没有加载上下文的情况下加载。

【讨论】:

我使用 Assembly.LoadFile 来加载以前版本的程序集,但我担心的是当省略程序集版本时使用 Assembly.Load 或 Type.GetType。我更新了问题。 我在回答中特别提到了这一点:“否则不能搞砸”。 好的,你有任何参考或解释为什么“不能以其他方式搞砸”吗? 谷歌“程序集加载上下文”。 最好的加载上下文文档:blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx。基本上,如果你使用Assembly.Load()以外的其他方式,你需要订阅AppDomain.AssemblyResolve以避免麻烦。

以上是关于.Net 同一个程序集的两个版本在一个 AppDomain 中加载时是不是存在潜在问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows Vista 和更高版本(Windows 7、2008)中查看 .NET 程序集的程序集版本?

。net工具

由于这个原因,在.net世界中使用了清单

.Net 选择错误引用的程序集版本

asp.net Web.config中assembly注册程序集的目的

ASP.NET MVC - 使用 C# 将引用不同程序集的模型从控制器传递到视图