Configure application startup in ASP.NET Core 6

If you are tracking the progress of
ASP.NET Core 6, you are probably aware of the new features being introduced.
One of the new and interesting features of ASP.NET Core 6 is the new way of
configuring web application startup in just a few lines of code. Currently this
new way of application startup has been introduced in empty project templates
but you can easily use it in any other project template (say, ASP.NET Core MVC
or Razor Pages). To that end this article shows you how standard ASP.NET Core
MVC project template generated code can be modified to use the new way of
application startup.
To begin with create a new ASP.NET Core MVC project based on built-in MVC
project template.

Once the project is created, open its Program.cs file. You will see the
following code in it:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder
(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
As you can see, this code contains the Main() method. The CreateHostBuilder()
uses the Host class from Microsoft.Extensions.Hosting namespace to create
IHostBuilder instance. You can also see how the Startup class is wired using the
UseStartup() method. If you developed any ASP.NET Core application before you
are probably aware of this code. So, I am not going into details of these
classes and methods. It should be noted that you will be able to use this
traditional way of configuring app startup in ASP.NET Core also. The new
approach is just an alternative to the approach shown above with its own
improvements and benefits.
At this stage a sample run of the application will look like this:

Now, let's modify this code to use the new approach of configuring a web
app startup.
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
using var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
app.Run();
}
Here, we used WebApplication class from Microsoft.AspNetCore.Builder
namespace and called its CreateBuilder() static method. The CreateBuilder()
method returns an WebApplicationBuilder object. You can then register MVC
services with the DI container using its Services property and
AddControllersWithViews() method.
Then Build() method is called on the WebApplicationBuilder to get an instance
of WebApplication. Then middleware wiring is done using extension methods of
this instance such as UseStaticFiles(), UseRouting(), and UseEndpoints().
Finally, Run() method is called to run the application.
As you can see, this code includes code that typically goes in
ConfigureServices() and Configure() method of the Startup class. Here, we didn't
use a separate Startup class at all making our code compact and easy to
understand.
Run the application by pressing F5 and you should see something like as shown
below:

What happened? Although the application runs as expected, the styling (CSS)
is missing in spite of calling UseStaticFiles(). This is because we haven't
configured the default static files folder in the above code.
Let's fix that issue. Add this line to the above code.
builder.Services.AddControllersWithViews();
builder.WebHost.UseWebRoot(
Path.Combine(Directory.GetCurrentDirectory()
, "wwwroot"));
using var app = builder.Build();
We used WebHost property of the builder and UseWebHost() method to specify an
absolute path of the static files folder (wwwroot in this case). After making
this change, the application will find the CSS files and will correctly render
the UI as shown in the first figure.
Next, we will now use top-level statements of C# to get rid of explicitly
writing the Main() method (and also the namespace and Program class
declaration).
Copy all the statements from the Main() method and paste them immediately
below the using directives:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.IO;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.WebHost.UseWebRoot(
Path.Combine(Directory.GetCurrentDirectory(),
"wwwroot"));
using var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
app.Run();
Also make sure to remove the project namespace, Program class, and the Main()
method. The Program.cs file should directly contain the statements shown above.
Our code is now using
C# top-level statements and hence we don't need to explicitly add the Main()
method. The new Empty project template of ASP.NET Core 6 uses similar code to
configure the web app.
What if you want to stick with the Startup class? This might be needed if you
are migrating from earlier versions of ASP.NET Core or prefer to isolate your
code in ConfigureServices() and Configure() methods. This can be accomplished as
shown below.
var builder = WebApplication.CreateBuilder(args);
builder.Host.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
using var app = builder.Build();
app.Run();
As you can see from above code, we used ConfigureWebHostDefaults() and
UseStartup() methods to configure the web application's startup class. Since we
are now using a separate Startup class we haven't included calls that go inside
ConfigureServices() and Configure() methods here (such as
AddControllersWithViews() and UseStaticFiles()). Also notice that we haven't
included UseWebRoot() call in this code because ConfigureWebHostDefaults() does
that for us.
Run the application and confirm that it works as expected.
That's it for now! Keep coding!!