--- title: Code samples migrated to the new minimal hosting model in 6.0 author: rick-anderson description: Learn how to migrate ASP.NET Core samples to the new minimal hosting model in 6.0. monikerRange: '>= aspnetcore-5.0' ms.author: riande ms.date: 10/22/2021 uid: migration/50-to-60-samples --- # Code samples migrated to the new minimal hosting model in ASP.NET Core 6.0 This article provides samples of code migrated to ASP.NET Core 6.0. ASP.NET Core 6.0 uses a new minimal hosting model. For more information, see [New hosting model](xref:migration/50-to-60#nhm). ## Middleware The following code adds the Static File Middleware to an ASP.NET Core 5 app: ```csharp public class Startup { public void Configure(IApplicationBuilder app) { app.UseStaticFiles(); } } ``` The following code adds the Static File Middleware to an ASP.NET Core 6 app: [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_mid)] [WebApplication.CreateBuilder](xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A) initializes a new instance of the class with preconfigured defaults. For more information, see ## Routing The following code adds an endpoint to an ASP.NET Core 5 app: ```csharp public class Startup { public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", () => "Hello World"); }); } } ``` In .NET 6, routes can be added directly to the without an explicit call to or . The following code adds an endpoint to an ASP.NET Core 6 app: [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_rt)] **Note:** Routes added directly to the execute at the ***end*** of the pipeline. ## Change the content root, app name, and environment ### ASP.NET Core 5 ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseContentRoot(Directory.GetCurrentDirectory()) .UseEnvironment(Environments.Staging) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup() .UseSetting(WebHostDefaults.ApplicationKey, typeof(Program).Assembly.FullName); }); ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_root)] For more information, see #### Change the content root, app name, and environment by environment variables or command line The following table shows the environment variable and command-line argument used to change the content root, app name, and environment: | feature | Environment variable | Command-line argument | | ------------- | ------------- | -- | | Application name | ASPNETCORE_APPLICATIONNAME | --applicationName | | Environment name | ASPNETCORE_ENVIRONMENT | --environment | | Content root | ASPNETCORE_CONTENTROOT | --contentRoot | ## Add configuration providers ### ASP.NET Core 5 ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration(config => { config.AddIniFile("appsettings.ini"); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_conf)] For detailed information, see [File configuration providers](xref:fundamentals/configuration/index?view=aspnetcore-6.0#file-configuration-provider) in . ## Add logging providers ### ASP.NET Core 5 ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.AddJsonConsole(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_log)] For more information, see . ## Add services ### ASP.NET Core 5 ```csharp public class Startup { public void ConfigureServices(IServiceCollection services) { // Add the memory cache services services.AddMemoryCache(); // Add a custom scoped service services.AddScoped(); } } ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_svc)] For more information, see . ## Customize IHostBuilder or IWebHostBuilder ### Customize IHostBuilder #### ASP.NET Core 5 ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30)); .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); ``` #### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_hb)] ### Customize IWebHostBuilder ### ASP.NET Core 5 ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { // Change the HTTP server implementation to be HTTP.sys based. webBuilder.UseHttpSys() .UseStartup(); }); ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_whb)] ## Change the web root By default, the web root is relative to the content root in the `wwwroot` folder. Web root is where the static files middleware looks for static files. Web root can be changed by setting the property on : ### ASP.NET Core 5 ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { // Look for static files in webroot. webBuilder.UseWebRoot("webroot") .UseStartup(); }); ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_wr)] ## Custom dependency injection (DI) container The following .NET 5 and .NET 6 samples use [Autofac](https://docs.autofac.org/en/latest/integration/aspnetcore.html) ### ASP.NET Core 5 **Program class** ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); ``` **Startup** ```csharp public class Startup { public void ConfigureContainer(ContainerBuilder containerBuilder) { } } ``` ### ASP.NET Core 6 ```csharp var builder = WebApplication.CreateBuilder(args); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); // Register services directly with Autofac here. Don't // call builder.Populate(), that happens in AutofacServiceProviderFactory. builder.Host.ConfigureContainer(builder => builder.RegisterModule(new MyApplicationModule())); var app = builder.Build(); ``` ## Access additional services `Startup.Configure` can inject any service added via the . ### ASP.NET Core 5 ```csharp public class Startup { // This method gets called by the runtime. Use this method to add services // to the container. public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); } // Anything added to the service collection can be injected into Configure. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, IService service, ILogger logger) { lifetime.ApplicationStarted.Register(() => logger.LogInformation( "The application {Name} started in the injected {Service}", env.ApplicationName, service)); } } ``` ### ASP.NET Core 6 In ASP.NET Core 6: * There are a few common services available as top level properties on . * Additional services need to be manually resolved from the `IServiceProvider` via [WebApplication.Services](xref:Microsoft.AspNetCore.Builder.WebApplication.Services). [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_af)] ## Test with WebApplicationFactory or TestServer ### ASP.NET Core 5 In the following samples, the test project uses `TestServer` and . These ship as separate packages that require explicit reference: #### WebApplicationFactory ```xml ``` #### TestServer ```xml ``` #### ASP.NET Core 5 code ```csharp public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHelloService helloService) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync(helloService.HelloMessage); }); }); } } ``` #### With TestServer ```csharp [Fact] public async Task HelloWorld() { using var host = Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(builder => { // Use the test server and point to the application's startup builder.UseTestServer() .UseStartup(); }) .ConfigureServices(services => { // Replace the service services.AddSingleton(); }) .Build(); await host.StartAsync(); var client = host.GetTestClient(); var response = await client.GetStringAsync("/"); Assert.Equal("Test Hello", response); } class MockHelloService : IHelloService { public string HelloMessage => "Test Hello"; } ``` #### With WebApplicationFactory ```csharp [Fact] public async Task HelloWorld() { var application = new WebApplicationFactory() .WithWebHostBuilder(builder => { builder.ConfigureServices(services => { services.AddSingleton(); }); }); var client = application.CreateClient(); var response = await client.GetStringAsync("/"); Assert.Equal("Test Hello", response); } class MockHelloService : IHelloService { public string HelloMessage => "Test Hello"; } ``` ### ASP.NET Core 6 [!code-csharp[](50-to-60-samples/samples/Web6Samples/Program.cs?name=snippet_test)] #### Project file (.csproj) The project file can contain one of the following: ```xml ``` Or ``` [assembly: InternalsVisibleTo("MyTestProject")] ``` An alternative solution is to make the `Program` class public. `Program` can be made public with [Top-level statements](/dotnet/csharp/fundamentals/program-structure/top-level-statements) by defining a `public partial Program` class in the project or in `Program.cs`: ```csharp var builder = WebApplication.CreateBuilder(args); // ... Configure services, routes, etc. app.Run(); public partial class Program { } ``` ```csharp [Fact] public async Task HelloWorld() { var application = new WebApplicationFactory() .WithWebHostBuilder(builder => { builder.ConfigureServices(services => { services.AddSingleton(); }); }); var client = application.CreateClient(); var response = await client.GetStringAsync("/"); Assert.Equal("Test Hello", response); } class MockHelloService : IHelloService { public string HelloMessage => "Test Hello"; } ``` The .NET 5 version and .NET 6 version with the `WebApplicationFactory` are identical by design.