The real entry point into the .NET runtime occurs in some undocumented classes and interfaces (Translation: Of course, you can use Reflector to view J). Very few people except Microsoft know about these interfaces, and the Microsoft guys They are not keen on talking about these details. They believe that these implementation details are of little use to developers who use ASP.NET to develop applications.
The worker process (ASPNET_WP.EXE in IIS5, W3WP.EXE in IIS6) hosts the .NET runtime and ISAPI DLL. It (the worker process) calls a small unmanaged interface of the COM object and ultimately sends the call to the ISAPIRuntime class. On an instance (Annotation: The original text is an instance subclass of the ISAPIRuntime class, but the ISAPIRuntime class is a sealed class, which is suspected to be a clerical error by the author, or subclass here does not mean subclass). The first entry into the runtime is This undocumented class implements the IISAPIRuntime interface (for the caller specification, this interface is a COM interface). This underlying COM interface based on IUnknown is a predetermined interface extended from ISAPI to ASP.NET. Figure 3 shows the IISAPIRuntime interface and its call signature (using Lutz Roeder's excellent .NET Reflector tool http://www.aisto.com/roeder/dotnet/). This is a good way to explore this step-by-step process. method.
Figure 3 - If you want to delve deeper into this interface, open Reflector and point to the System.Web.Hosting namespace. The ISAPI DLL opens access to ASP.NET by calling a hosted COM interface. ASP.NET receives a non-binary link pointing to the ISAPI ECB. Managed pointer. This ECB contains the ability to access the complete ISAPI interface used to receive requests and send responses back to IIS.
The IISAPIRuntime interface serves as the interface point between unmanaged code extending from ISAPI and ASP.NET (directly related in IIS6). (via Named Pipes in IIS5). If you look inside this class, you will find the ProcessRequest function with the following signature:
[return: MarshalAs(UnmanagedType.I4)]
int ProcessRequest([In] IntPtr ecb,
[In, MarshalAs(UnmanagedType.I4)] int useProcessModel);
the ecb parameter is the ISAPI Extension Control Block (Extention Control Block), which is passed to the ProcessRequest function as an unmanaged resource. This function takes the ECB as the basic Input and output interface, used with Request and Response objects. ISAPI ECB contains all low-level request information, such as server variables, input streams for form variables and output streams for writing data back to the client. This An ecb reference basically provides all the functionality for accessing a resource that can be accessed by ISAPI requests. ProcessRequest is the initial entry and exit point for this resource (ecb) to managed code.
ISAPI extensions handle requests asynchronously. In this mode ISAPI The extension immediately returns the call to the worker process or IIS thread, but the ECB will remain available for the lifetime of the current request. The ECB contains a mechanism to let ISAPI know that the request has been processed (through the ecb.ServerSupportFunction method) (Annotation: More For information, see the article on developing ISAPI extensions), which causes the ECB to be released. This asynchronous processing method immediately releases the ISAPI worker thread and passes the processing to a separate thread managed by ASP.NET.
ASP.NET receives Reference to ecb and use it internally to receive information about the current request, such as server variables and POST data. It also returns information to the server. ecb remains accessible (stay alive) until the request is completed or the timeout expires. This way ASP.NET can continue to communicate with it until the request processing is completed. The output is written to the ISAPI output stream (using ecb.WriteClient()) and the request is completed. The ISAPI extension is notified that the request processing is complete and releases the ECB. This implementation is very efficient, because the .NET classes are essentially just a very "thin" wrapper around the efficient, unmanaged ISAPI ECB.
Loading .NET - a bit mysterious
.Let's take a step back from here: I Skipping over how the .NET runtime is loaded. This is where things get a little fuzzy. I didn't find any documentation on this process, and since we're talking about native code, there's no good way to do it. to decompile the ISAPI DLL and figure it out (the code that loads the .NET runtime).
The best guess I can make is that when the ISAPI extension receives the first request for an extension that maps to ASP.NET, the job The process loads the .NET runtime. Once the runtime exists, unmanaged code can request an instance of ISAPIRuntime for a specified virtual directory if it does not already exist. Each virtual directory has its own application domain ( AppDomain), when an independent application (referring to an ASP.NET program) is started, ISAPIRuntime has always existed in the application domain from the startup process. Instantiation (Annotation: should refer to the instantiation of ISAPIRuntime) seems to be through COM This is done because the interface methods are exposed as COM callable methods.
When the first request for a virtual directory comes, the System.Web.Hosting.AppDomainFactory.Create() function is called to create an instance of ISAPIRuntime. This begins the application's startup process. This call receives the application's type, module name, and virtual directory information, which is used by ASP.NET to create the application domain and start the ASP.NET program for this virtual directory. The HttpRuntime Instances (Annotation: The original text is This HttpRuntime derived object, but HttpRuntime is a sealed class, which is suspected to be an error in the original text) are created in a new application domain. Each virtual directory (that is, an ASP.NET application is hosted) is hosted in A separate application domain, and they will only be loaded when a specific ASP.NET program is requested. The ISAPI extension manages instances of these HttpRuntime objects and routes internal requests based on the requested virtual directory. to the correct HttpRuntime object.
Figure 4 - ISAPI requests are sent to ASP.NET's HTTP pipeline using some undocumented classes, interfaces and calling many factory methods. Each web application/virtual directory runs in its own application domain, and the caller ( Annotation: ISAPI DLL) maintains a reference to the IISAPIRuntime interface to trigger ASP.NET request processing.