代码之家  ›  专栏  ›  技术社区  ›  Omar

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

  •  5
  • Omar  · 技术社区  · 15 年前

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

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

    我引用了位于 extras 在视图中的文件夹中,它们工作良好(使用 <%@ Import Namespace="myNameSpace" %> )

    我的问题

    1. 当那条线被调用时会发生什么?
    2. 组件装载在哪里?
    3. 为什么我不能覆盖位于 额外的 文件夹包含 myNameSpace 有新版本吗?(我收到一个错误,说程序集在另一个程序中是“打开的”)。
    4. 是否有方法在不重新启动应用程序的情况下用较新版本覆盖程序集?
    2 回复  |  直到 15 年前
        1
  •  5
  •   Josh    15 年前

    1)导入实际上在运行时不做任何操作。这是一种编译时的便利,只允许您引用使用其非限定名称的类型,例如环境而不是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可能只为指定了“bin”文件夹 shadow copying .

        2
  •  0
  •   Burt    15 年前
    1. 我认为这与C_中的using语句相同,它基本上意味着名称空间的类现在可以在yoru页面中使用。
    2. 程序集可能将由aspnethp.exe进程加载到内存中。
    3. 如果程序集当前正在使用,您将收到此错误消息
    4. 重新启动是我知道的最安全的方法,您可以使用依赖注入或延迟绑定来实现相同的结果。我想知道为什么在应用程序运行时要切换程序集?