加载程序集时会发生什么?

时间:2010-03-06 05:47:48

标签: asp.net-mvc assemblies

在我的ASP.NET MVC应用程序中,我有以下设置:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="bin;extras"/>

我引用了位于视图中extras文件夹中的程序集,它们运行良好(使用<%@ Import Namespace="myNameSpace" %>)。

我的问题

  1. 调用该行时会发生什么?
  2. 装配装置在哪里?
  3. 为什么我不能使用较新版本覆盖包含extras的{​​{1}}文件夹中的程序集? (我收到一个错误,说组件在另一个程序中“打开”)
  4. 有没有办法在没有重新启动应用程序的情况下使用较新版本覆盖程序集?

2 个答案:

答案 0 :(得分:5)

1)导入实际上并没有在运行时做任何事情。这是一个编译时的便利,只是让你使用他们的非限定名称来引用类型,例如Environment而不是System.Environment。

2)使用常规装配探测规则加载装配。 CLR在这些私有探测路径之前检查的各个位置,因此记住这一点很重要。如果引用强名称程序集并希望在私有探测路径中找到该程序集,则首选GAC中具有相同强名称(名称,版本,公钥等)的程序集。这有时会导致意外行为,通常是由于在AssemblyInfo.cs中对汇编版本进行硬编码而忘记更新它。

3)加载后,如果不卸载AppDomain,则无法卸载程序集。但ASP.NET使用“阴影复制”,这意味着在加载之前将程序集复制到临时路径。这应该使原始组件解锁并且能够被覆盖。在我的头顶,我不知道为什么你会得到关于锁定组件的错误。在普通的Windows应用程序中,这是完全正常的和预期的。但ASP.NET的设计使您可以在应用程序运行时覆盖内容,代码,程序集等,从而产生#4。

4)在实践中,没有。由于无法卸载程序集,因此无法在不重新启动Web应用程序的情况下升级程序集。从技术上讲,您可以加载多个版本的程序集,但这不会为您提供所需的结果。任何编译时引用仍将引用旧程序集,如果您尝试使用新程序集,则会获得各种无效的转换异常。但正如我在#3中所说,ASP.NET升级程序集应该像替换文件一样简单,并且应该自动发生。您不必手动重新启动IIS或工作进程。

以下链接可能会引起您的兴趣。

How the Runtime Locates Assemblies
Best Practices for Loading Assemblies
Shadow Copying Assemblies
Unloading Assemblies - Suzanne Cook

<强>更新 在阅读了有关阴影复制的更多内容之后,我认为你可能在extras文件夹中看到锁定程序集问题的原因是ASP.NET可能只为shadow copying指定了“bin”文件夹。

答案 1 :(得分:0)

  1. 我认为这与C#中的using语句相同,它基本上意味着命名空间的类现在可以在yoru页面中使用。
  2. 程序集可能会被aspnetwp.exe进程
  3. 加载到内存中
  4. 如果当前正在使用程序集,您将收到此错误消息
  5. 重启是我所知道的最安全的方法,您可以使用依赖注入或后期绑定来实现相同的结果。我想知道你为什么要在应用程序运行时切换程序集?