在我的 ASP.NET MVC 应用程序中,我进行了以下设置:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;extras"/>
我引用了位于视图中的 extras
文件夹中的程序集,并且它们运行良好(使用 <%@ Import Namespace= “myNameSpace”%>
)。
我的问题
- 拨打该线路后会发生什么?
- 程序集加载到哪里?
- 为什么我无法使用新版本覆盖包含
myNameSpace
的 extras
文件夹中的程序集? (我收到一条错误消息,说该程序集在另一个程序中“打开”)
- 有没有办法在不重新启动应用程序的情况下用较新的版本覆盖程序集?
In my ASP.NET MVC application, I have the following setup:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;extras"/>
I have referenced assemblies located in the extras
folder in the views and they have worked perfectly (using <%@ Import Namespace="myNameSpace" %>
).
My questions
- What happens when that line is called?
- Where is the assembly loaded?
- Why is it that I can't overwrite the assembly located in the
extras
folder that contains myNameSpace
with a newer version? (I get an error saying that the assembly is "open" in another program)
- Is there a way to overwrite the assembly with a newer version without having the application restart?
发布评论
评论(2)
1)导入实际上在运行时并不执行任何操作。这是一种编译时便利,让您可以使用非限定名称(例如 Environment 而不是 System.Environment)来引用类型。
2) 使用正常的程序集探测规则加载程序集。 CLR 在这些私有探测路径之前检查各个位置,因此记住这一点很重要。如果您引用强名称程序集并希望在私有探测路径中找到该程序集,则首选 GAC 中具有相同强名称(名称、版本、公钥等)的程序集。这有时会导致意外行为,通常是由于在 AssemblyInfo.cs 中硬编码程序集版本并忘记更新它而导致的。
3) 一旦加载,程序集就无法在不卸载AppDomain 的情况下卸载。但 ASP.NET 使用“影子复制”,这意味着程序集在加载之前会被复制到临时路径。这应该会使原始程序集解锁并且能够被覆盖。在我的脑海中,我不确定为什么您会收到有关锁定程序集的错误。在正常的 Windows 应用程序中,这是完全正常的并且是预期的。但 ASP.NET 的设计目的是让您可以在应用程序运行时覆盖内容、代码、程序集等,这导致了#4。
4)实际上,没有。由于无法卸载程序集,因此在不重新启动 Web 应用程序的情况下无法升级程序集。从技术上讲,您可以加载程序集的多个版本,但这不会给您带来所需的结果。任何编译时引用仍将引用旧程序集,并且如果您尝试使用新程序集,您将收到各种无效的强制转换异常。但正如我在 #3 中所说,使用 ASP.NET 升级程序集应该像替换文件一样简单,并且应该自动发生。您不必手动重新启动 IIS 或工作进程。
您可能会对以下链接感兴趣。
运行时如何定位程序集
加载程序集的最佳实践
卷影复制程序集
卸载程序集 - Suzanne Cook
更新
在阅读了有关卷影复制的更多内容后,我认为您可能会在 extras 文件夹中看到锁定程序集问题的原因是 ASP.NET 可能只为 卷影复制。
1) Import doesn't actually do anything at runtime. It's a compile-time convenience that just lets you refer to types using their unqualified names such as Environment instead of System.Environment.
2) The assembly is loaded using normal assembly probing rules. The CLR checks various locations before these private probing paths so it's important to keep that in mind. If you reference a strong-named assembly and expect to find that assembly in a private probing path, an assembly with the same strong name (name, version, public key, etc) in the GAC would be preferred. This can sometimes lead to unexpected behavior and is usually caused by hard coding an assembly version in your AssemblyInfo.cs and forgetting to update it.
3) Once loaded, an assembly cannot be unloaded without unloading the AppDomain. But ASP.NET uses "shadow copying" which means assemblies are copied to a temporary path before being loaded. This should leave the original assembly unlocked and able to be overwritten. Off the top of my head, I am not sure why you'd be getting the error about locked assemblies. In a normal Windows application, this would be totally normal and expected. But ASP.NET is designed so that you can overwrite content, code, assemblies, etc while the application is running, which leads to #4.
4) In practice, no. Because an assembly cannot be unloaded, there is no way to upgrade an assembly without the web application being restarted. Technically speaking, you can load multiple versions of an assembly but this would not give you the desired results. Any compile-time references would still reference the old assembly and you'd get all kinds of invalid cast exceptions if you tried to use the new assembly. But as I said in #3, with ASP.NET upgrading assemblies is supposed to be as simple as replacing the files and should happen automatically. You shouldn't have to restart IIS or worker processes manually.
The following links may be of interest.
How the Runtime Locates Assemblies
Best Practices for Loading Assemblies
Shadow Copying Assemblies
Unloading Assemblies - Suzanne Cook
UPDATE
After reading a bit more on shadow copying, I think the reason you might be seeing the issue of locked assemblies in the extras folder is that ASP.NET probably only specifies the "bin" folder for shadow copying.