为什么ASP.NET以不同的方式解析程序集引用? [英] Why do ASP.NET resolve assembly references differently?

查看:109
本文介绍了为什么ASP.NET以不同的方式解析程序集引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很努力地找到一个类似的问题来获得一些线索,但是似乎没有人描述我们遇到的情况,所以就这样.

I really tried hard to find a similar issue to get some leads, but no one seems to describe the case we are having, so here it goes.

背景

我们提供的产品具有以下一般设计:

We have a product with the following general design:

[本地安装文件夹]

[Local installation folder]

  • 包含一组.NET程序集,实现了我们大部分产品功能.
  • 示例: Implementation1.dll Implementation2.dll

[GAC]

  • ClientAPI.dll.我们的客户端程序集,将从最终用户Visual Studio项目中引用.在本地安装文件夹中具有对实现dll的强烈引用.

在ClientAPI.dll中,我们有一个入口点,我们需要最终用户项目来调用.让我们称之为Initialize().

In ClientAPI.dll, we have an entrypoint we require end user projects to invoke. Lets call it Initialize().

我们在Initialize中所做的第一件事是使用AssemblyResolve事件在当前域上安装所谓的程序集解析处理程序.该处理程序将知道如何使用Assembly.Load()定位实现dll并将其加载到客户端进程中.

The very first thing we do in Initialize is to install a so called assembly resolve handler on the current domain, using the AssemblyResolve event. This handler will know how to locate the implementation dll's and load them into the client process, using Assembly.Load().

考虑一个控制台应用程序.看起来像这样:

Consider a console application. It will look something like:

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的引用.

Now, all is good in the console/windows forms/WPF world. Our assembly resolve handler is properly installed and invoked, and it can successfully resolve references to the implementation DLL's once ClientAPI.dll require their functionality.

问题陈述

话虽如此,我们打算不只支持控制台或WPF应用程序,因此我们依赖于ASP.NET中的相同设计.因此,在VS 2010中创建一个新的ASP.NET Web应用程序项目,我们认为一切都将变得如此简单:

With that being said, we intend not to support only console or WPF applications, so we were relying on the same design in ASP.NET. Hence, creating a new ASP.NET Web Application project in VS 2010, we figured everything would be as straightforward as:

class Globals : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        ClientAPI.Initialize();

        // ...
    }
}

在ASP.NET运行时环境中停留了20到30个小时,在开发服务器和IIS中尝试以上操作,我们发现事情并没有达到我们的预期.

A few 20-30 hours of dwelling in the ASP.NET runtime universe, trying the above in both the development server and in IIS, we've learned that things there are not really as we expected.

事实证明,在ASP.NET中,只要在任何地方引用了ClientAPI类,就会立即解决对所有其他程序集的所有引用.不仅如此:结果被缓存(根据设计,从我们发现.NET 2.0以来),这意味着我们根本没有机会尝试协助CLR.

It turns out that in ASP.NET, as soon as the ClientAPI class is referenced anywhere, all references it has to any other assemblies are instantly resolved. And not only that: the results are cached (by design, since .NET 2.0 we've found), meaning we never have a chance at all trying to assist the CLR.

在没有进一步阐述我们尝试过和学习到的不同事物的情况下,基本上可以归结为我们遇到的这个问题:

Without further elaboration about the different things we've tried and learned, it basically comes down to this question we have:

为什么ASP.NET解析这样的引用?它与其他类型的应用程序的操作方式不兼容,甚至与.NET/CLR运行时的文档也不兼容,它指定了在首次需要时(即何时)对外部类型/程序集的引用进行解析.首先在代码中使用).

Why is ASP.NET resolving references like this? It is not compatible with how other types of applications does it, and even more, it is not according to the documentation of .NET / the CLR runtime, specifying that references to external types / assemblies are to be resolve when first needed (i.e when first used in code).

任何见解/想法都将受到高度赞赏!

Any kind of insight/ideas would be highly appreciated!

推荐答案

Windows Forms/WPF应用程序在单独的客户端计算机上运行(因此在单个本地上下文中运行),而ASP.Net在IIS内的应用程序中运行服务器或一组服务器上的池(在Web场情况下).加载到应用程序池中的任何内容都可用于整个应用程序(因此,将在连接到该应用程序的所有客户端之间共享).

Windows Forms / WPF applications run on individual client machines (and therefore run in a single, local context), whereas ASP.Net runs within IIS, within an application pool, on a server or set of servers (in a web farm situation). Whatever is loaded in to the application pool is available to the entire application (and therefore is shared between all clients who connect to the application).

HttpApplication.Application_Start一次执行 .它不会像Winforms应用程序那样在每个客户端上执行-如果需要为每个连接的客户端初始化某些内容,请使用Session_Start或Session_OnStart,但是然后可能会遇到服务器内存问题,具体取决于有多少客户端将要连接到您的Web应用程序.这还取决于您的类是否为单例,以及Initialize()方法是否为静态.如果您遇到以上任何一种情况,都将很快遇到跨线程问题.

HttpApplication.Application_Start is executed once, when the application starts up. It is not executed per client as it would be with a Winforms application - if you need to initialize something for every client that connects, use Session_Start or Session_OnStart, but then you may run in to memory issues with the server, depending on how many clients are going to connect to your web application. This also depends on whether your class is a singleton, and if the Initialize() method is static. If you have either of those situations, you're going to run in to cross-threading problems fairly quickly.

此外,值得注意的是,闲置的IIS应用程序池将在一段时间后重置.例如,如果没人过夜使用该Web应用程序,则IIS将刷新该应用程序的应用程序池并释放内存.可以在IIS管理中更改这些设置,但是在执行此操作时要小心-更改这些设置以规避设计不良的对象(或非针对Web应用程序设计的对象)会带来更多问题.

Additionally, it's worth noting that an idle IIS application pool will reset itself after a period of time. If no one uses the web application overnight, for example, IIS will flush the application's application pool and free up memory. These settings can be changed within IIS administration, but you should be careful when doing so - changing these settings to circumvent a badly designed object (or an object that isn't designed for a web application) can create even more problems.

仅供参考-我有点大惊小怪,但为避免疑问,该对象已被 not 缓存-是的,它已加载到内存中,但是如何管理内存对象的设计方式(在网络世界中缓存是完全不同的事情,可以在应用程序的许多不同层中实现).

FYI - I'm being a little fussy, but for the avoidance of doubt, the object is not cached - yes, it is loaded in to memory, but how the memory is managed is up to how you've designed the object (caching in the web world is an entirely different thing, and can be implemented in many different layers of your application).

不要试图使Web应用程序像Windows应用程序一样工作;您只会为自己制造更多问题!

Don't try and make a web application act like a windows application; you'll just create yourself more problems!

这篇关于为什么ASP.NET以不同的方式解析程序集引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆