【发布时间】:2011-08-11 12:13:08
【问题描述】:
我真的很努力地寻找一个类似的问题来获得一些线索,但似乎没有人描述我们遇到的情况,所以就这样吧。
背景
我们的产品具有以下一般设计:
[本地安装文件夹]
- 包含一组 .NET 程序集,实现了我们的大部分产品功能。
- 示例:Implementation1.dll、Implementation2.dll
[GAC]
- ClientAPI.dll。我们的客户端程序集,从最终用户 Visual Studio 项目中引用。强烈引用本地安装文件夹中的实现 dll。
在 ClientAPI.dll 中,我们有一个入口点,需要最终用户项目调用。让我们称之为Initialize()。
我们在Initialize 中做的第一件事是使用AssemblyResolve 事件在当前域上安装一个所谓的程序集解析处理程序。该处理程序将知道如何定位实现 dll 并将它们加载到客户端进程中,使用 Assembly.Load()。
考虑一个控制台应用程序。它看起来像:
class Class1
{
void Main(string[] args)
{
ClientAPI.Initialize();
// Use other API's in the assembly, possibly internally referencing the
// implementation classes, that now will be resolved by our assembly
// resolve handler.
}
}
现在,控制台/Windows 窗体/WPF 世界中的一切都很好。我们的程序集解析处理程序已正确安装和调用,一旦 ClientAPI.dll 需要它们的功能,它就可以成功解析对实现 DLL 的引用。
问题陈述
话虽如此,我们不打算只支持控制台或 WPF 应用程序,因此我们依赖 ASP.NET 中的相同设计。因此,在 VS 2010 中创建一个新的 ASP.NET Web 应用程序项目,我们认为一切都会像这样简单:
class Globals : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
ClientAPI.Initialize();
// ...
}
}
在 ASP.NET 运行时世界中停留了 20 到 30 个小时,在开发服务器和 IIS 中尝试了上述内容,我们了解到那里的事情并不像我们预期的那样。
事实证明,在 ASP.NET 中,只要在任何地方引用 ClientAPI 类,它对任何其他程序集的所有引用都会立即解析。不仅如此:结果被缓存(设计上,我们发现了 .NET 2.0),这意味着我们根本没有机会尝试帮助 CLR。
如果不进一步详细说明我们尝试和学习的不同事物,基本上可以归结为我们遇到的这个问题:
为什么 ASP.NET 会像这样解析引用?它与其他类型的应用程序如何做到这一点不兼容,更重要的是,它不是根据 .NET/CLR 运行时的文档,指定对外部类型/程序集的引用将在第一次需要时解析(即当首先在代码中使用)。
任何形式的见解/想法都将受到高度赞赏!
【问题讨论】:
-
好问题。需要一些颠簸。
-
我最近也遇到了这个问题。这是非常令人沮丧的,没有真正好的解决方案。现在在 ASP.NET 4 中以 PreApplicationStartMethodAttribute 的形式存在一种解决方案,它允许您在 ASP.NET 管道的早期运行代码,从而允许您处理程序集的解析。 NuGet 上可用的 WebActivator 项目利用了这个新属性并对其进行了扩展。当然这只适用于 ASP.NET 4...更多信息可以在这里找到:haacked.com/archive/2010/05/16/…
标签: asp.net gac assembly-references assemblyresolve