ASP.NET Core - Program.cs

ASP.NET Core web application is actually a console project which starts executing from the entry point public static void Main() in Program class where we can create a host for the web application.

The steps for creating a host in ASP.NET Core 1.x is slightly different in ASP.NET Core 2.x. Let's understand Program class in ASP.NET Core 1.x application so that it will be easy to understand it in ASP.NET Core 2.x.

Setup Host in ASP.NET Core 1.x

The following is a typical Program.cs in ASP.NET Core 1.x.

Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace MyFirstCoreApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

Every ASP.NET Core web application requires a host to be executed. In the above Main() method, we configure a web hosting environment for the ASP.NET Core 1.x web application. A host must implement IWebHost interface. Let's understand the above code step by step.

First, var host = new WebHostBuilder()

The WebHostBuilder class is the helper class to create and configure a host for a web application. So, first of all we will have to create an object of it.

Note:
WebHostBuilder class is included in .NET Core API. However, we can create our own helper class by implementing IWebHostBuilder interface for custom hosting requirement.

.UseKestrel()

The UseKestrel() method is an extension method which specifies Kestrel as an internal web server. The Kestrel is an open-source, cross-platform web server for ASP.NET Core. It is designed to be used behind proxy because it has not yet matured to be exposed as a full-fledge web server.

ASP.NET Core application can be a cross-platform application so it can be used with any web server, and not only IIS. Hence, there will be an external web server such as IIS, Apache, Nginx etc. which will dispatch http requests to the internal web server Kestrel. Learn more about web servers in ASP.NET Core here.

.UseContentRoot(Directory.GetCurrentDirectory())

The UseContentRoot() method specifies the current directory as a root directory which will be src folder in the default ASP.NET Core project. The content root directory determines where the content files are located such as MVC view files, CSS, images etc.

.UseIISIntegration()

The UseIISIntegration() method specifies the IIS as the external web server or the reverse proxy server.

.UseStartup<Startup>()

The UseStartup<startup>() method specifies the Startup class to be used by the web host. Visual Studio creates Startup.cs by default with every new ASP.NET Core application. This Startup class is like Global.asax of .NET framework where you can configure request pipeline (middleware). We may give any other name to the Startup class instead of Startup. We just need to specify it as a generic parameter in UseStartup<T>() method. You will learn about it in the next chapter.

And lastly, the Build() method returns an instance of IWebHost using the configuration specified above.

So now, we have built our hosting environment and it's time to start the web application.

host.Run();

The Run() method starts the web application and blocks the calling thread till the host is shutdown. The command line application will become web application from this point onwards.

Thus, ASP.NET Core application starts from the Main() method of the Program class where you can build the hosting environment and start the web application.

Setup Host in ASP.NET Core 2.x

The following is the Program class in ASP.NET Core 2.x:

Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace MyFirstCoreApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

As you can see above, the Main() method calls method expression BuildWebHost() to build web host with pre-configured defaults. The BuildWebHost expression can also be written as a method that returns IWebHost as shown below.

public static void Main(string[] args)
{
    BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) 
{
    return WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();
}

Let's understand hosting steps.

The WebHost is a static class which can be used for creating an instance of IWebHost and IWebHostBuilder with pre-configured defaults. The CreateDefaultBuilder() method creates a new instance of WebHostBuilder with pre-configured defaults. Internally, it configures Kestrel, IISIntegration and other configurations. The following is CreateDefaultBuilder() method from the source code on GitHub.

CreateDefaultBuilder()
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
    var builder = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;

            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

            if (env.IsDevelopment())
            {
                var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                if (appAssembly != null)
                {
                    config.AddUserSecrets(appAssembly, optional: true);
                }
            }

            config.AddEnvironmentVariables();

            if (args != null)
            {
                config.AddCommandLine(args);
            }
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
        })
        .UseIISIntegration()
        .UseDefaultServiceProvider((context, options) =>
        {
            options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
        });

    return builder;
}

As you can see above, the CreateDefaultBuilder method creates an instance of WebHostBuilder and sets up Kestrel, content root directory, IIS integration which is same as ASP.NET Core 1.x Main() method.

It also calls ConfigureAppConfiguration() to load configurations from appsettings.json files, environment variables and user secrets. The ConfigureLogging() method setup logging to console and debug window.

Thus, Program.cs in ASP.NET Core 2.x makes it easy for us to setup a web host.

Learn about Startup.cs in the next chapter.