Why does ASP.NET allow assembly references differently?

I really tried to find a similar problem in order to get some conclusions, but no one seems to describe the case that we have, so here it is.

Background

We have a product with the following general design:

[Local installation folder]

  • Contains a set of .NET collections that implement the bulk of the functionality of our product.
  • Example: Implement1.dll, Implementation2.dll

[GAU]

  • ClientAPI.dll. Our client build that Visual Studio end-user projects will reference. It has strong links to implementation DLLs in the local installation folder.

In ClientAPI.dll, we have an entry point that requires end-user projects. Lets call it Initialize() .

The very first thing we do in Initialize is to install the so-called assembly solution handler in the current domain using the AssemblyResolve event. This handler will know how to find the DLL implementation and load them into the client process using Assembly.Load() .

Consider a console application. It will look something like this:

 class Class1 { void Main(string[] args) { ClientAPI.Initialize(); // Use other API in the assembly, possibly internally referencing the // implementation classes, that now will be resolved by our assembly // resolve handler. } } 

Now everything is fine in the console / windows forms / WPF world. Our assembly resolution handler is correctly installed and invoked, and it can successfully resolve references to the implementation DLLs after ClientAPI.dll requires their functionality.

Description of the problem

With this in mind, we do not intend to support only console or WPF applications, so we relied on the same design in ASP.NET. Therefore, when creating a new ASP.NET web application project in VS 2010, we thought that everything would be as simple as:

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

After 20-30 hours of being in the ASP.NET universe at run time, having tried the above on both the development server and IIS, we found out that it wasn’t what we expected.

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

Without further elaboration of the various things that we tried and learned, basically it comes down to the following question:

Why does ASP.NET allow such links? It is incompatible with the way other types of applications do it, and even more, it does not conform to the documentation of the .NET / CLR environment, indicating that references to external types / assemblies should be allowed when necessary (i.e. when first used in code).

Any ideas / ideas would be highly appreciated!

+6
source share
1 answer

Windows Forms / WPF applications run on separate client computers (and therefore run in the same local context), while ASP.Net runs in IIS in the application pool on a server or multiple servers (in a web farm). Everything that is uploaded to the application pool is accessible to the entire application (and, therefore, is shared by all clients that connect to the application).

HttpApplication.Application_Start runs once when the application starts. It does not run on the client, as it would with the Winforms application - if you need to initialize something for each connected client, use Session_Start or Session_OnStart, but then you may encounter memory problems with the server, depending on how many clients are going Connect to your web application. It also depends on whether your class is single, and if the Initialize () method is static. If you have any of these situations, you will quickly deal with cross-thread issues.

In addition, it is worth noting that an empty IIS application pool will reset itself after a certain period of time. For example, if no one is using a web application overnight, IIS will clear the application pool and free up memory. These settings can be changed in IIS administration, but you should be careful - changing these settings to bypass a poorly designed object (or an object that is not intended for a web application) can create even more problems.

FYI - I'm a little fussy, but, to avoid doubt, the object is not cached - yes, it is loaded into memory, but how memory is managed depends on how you created the object (caching in the web world is a completely different thing and can be implemented in many different layers of your application).

Do not try to make a web application act like a Windows application; you just create more problems for yourself!

0
source

Source: https://habr.com/ru/post/894824/


All Articles