简体   繁体   中英

Instantiation of ASP.NET Core application in production

ASP.NET Core starts executing from Main method which lies in Program class inside Program.cs file. That builds a web hosting environment and tell that web host to start running. Then, there is startup.cs file.

When developing a .NET Core web application, I have to build it locally (by Ctrl-F5 for example). When doing that, Main method is running. Every next time I want to open my web application, given IIS Express has already been launched, I am just writing eg http://localhost:65040 . By doing that, Main method is not running again, but everything works fine (routing etc..). So, I have the following question :

How .NET Core knows what to do upon the reception of the above Http request ( http://localhost:65040 )? For example, how does it implement routing since

app.UseMvc(routes =>
{
    app.UseMvcWithDefaultRoute();
})

in Startup.cs is not running again? There is no need for that because IIS has already been informed?

And if the above thought is correct what exactly is happening in deployment ? Then our Http requests never trigger program.cs and startup.cs . So, in which way the remote web server is being informed about stuff how to implement routing etc?

Regardless of hosting you choose for ASP.Net Core Application (IIS or self hosting via Kestrel), methods Program.Main() , Startup.ConfigureServices() and Startup.Configure() are executed exactly once during hosting process startup.

It's obvious that Program.Main() is executed when you launch exe file with Kestrel web server within. It could be however not obvious whether it's actually called when hosting in IIS. It is so actually. When ASP.Net Core Application is integrated with IIS, it's usually executed by dotnet.exe runner (it's also possible to configure the launch of application .exe file). You could check it in web.config created during adding of application:

<configuration>
  <system.webServer>
    <!-- ... -->
    <aspNetCore processPath="dotnet" arguments=".\TestMvcApplication.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

So it basically the same as when you run application with command dotnet.exe TestMvcApplication.dll . Program.Main() is executed in this case, with Startup methods following.

Without Main() method that basically builds the web host, ASP.Net Core application just can not run.

When you fire subsequent queries, they are processed by the same hosting application (I mean the same Windows process here). And all configuration required by ASP.Net Core (like routing, middleware, services etc.) is already wired up within this process. That's why ASP.Net Core is able to process the requests.

I hope this is an answer for your question. Here are some useful links that could be helpful:

Hosting in ASP.NET Core

Host ASP.NET Core on Windows with IIS

Application startup in ASP.NET Core

Here's what happens when you run your program from a high level view:

First like any other .NET application the Main method will be called, since that's the starting point in any .NET application.

If it's a console app then nothing special, it just runs the codes and exits the program.

But for web applications the program needs to run forever and listen to incoming HTTP requests. So how can we say to our app to do this for us? We have to configure it. Like any other framework, .NET Core has some rules and conventions, here's the simplest way you can build a web app in .NET Core:

public class Program
{
    public static void Main()
    {
        new WebHostBuilder()
            .UseKestrel()
            .Configure(app =>
            {
                app.Run(async context => await context.Response.WriteAsync("Hello World!"));
            })
            .Build()
            .Run();
    }
}

So what happens here is that the OS runs the Main method in a process (with a processing thread). We create a WebHostBuilder and configure it to use Kestrel as webserver and send back "Hello World!" string to any incoming HTTP request. Then we build and run our WebHostBuilder .

What Configure method does is that it creates a pipeline so every request will go through the logic of that pipeline. All the method you see in the Configure method will just add extra logic to the pipeline like authentication, static content serving, configuring routes and etc.

I should note here that for using some features we have to add them to our program first, which will be done in ConfigureServices() method, which runs before Configure() method.

The important method here is Run() , which blocks the calling thread (the thread that called the Main method). So the Main method will never complete, otherwise it would exit the program. But our WebHost is running in the background and will respond to HTTP requests.

So to wrap up, the Main method will run only once during the application startup and it creates and configures a WebHost to serve the HTTP requests. There is no need to run the Main method or create a new WebHost for every request.

These were some basics, if you want to learn more you should read Microsoft Docs. There are many useful informations there.

After a lot of studying and experiments, I found that the key point into my answer is the following: Program.cs and Startup.cs are running only the very first time an Http request is being made. It is this first time which configures Kestrel and informs it about everything it has to know for any subsequent request (eg routing).

To be honest, I do not know how exactly the application distinguishes between the very first request and the other ones , however what I described above is definitely happening to both development and production.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM