【问题标题】:What happens when I load an assembly?加载程序集时会发生什么?
【发布时间】:2011-01-24 09:23:22
【问题描述】:

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

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

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

我的问题

  1. 调用该行时会发生什么?
  2. 程序集在哪里加载?
  3. 为什么我不能用较新的版本覆盖位于包含myNameSpaceextras 文件夹中的程序集? (我收到一条错误消息,提示该程序集在另一个程序中“打开”)
  4. 有没有办法在不重新启动应用程序的情况下用较新版本覆盖程序集?

【问题讨论】:

    标签: asp.net-mvc assemblies


    【解决方案1】:

    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”文件夹。

    【讨论】:

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

      【讨论】:

      • #4:将其替换为更新版本。运行时这可能吗?
      • 如果您使用依赖注入并针对接口编程,您可以轻松完成。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多