Compartir a través de


Ejemplos de código migrados al nuevo modelo de hospedaje mínimo en ASP.NET Core en .NET 6

En este artículo se proporcionan ejemplos de código migrado a ASP.NET Core en .NET 6. ASP.NET Core en .NET 6 usa un nuevo modelo de hospedaje mínimo. Para obtener más información, consulte Nuevo modelo de hospedaje.

Software intermedio

El código siguiente agrega el middleware de archivos estáticos a una aplicación de .NET 5:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseStaticFiles();
    }
}

El código siguiente agrega el middleware de archivos estáticos a un ASP.NET Core en la aplicación .NET 6:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseStaticFiles();

app.Run();

WebApplication.CreateBuilder inicializa una nueva instancia de la clase WebApplicationBuilder con valores predeterminados preconfigurados. Para obtener más información, consulte Middleware de ASP.NET Core.

Enrutamiento

El código siguiente agrega un punto de conexión a una aplicación de .NET 5:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", () => "Hello World");
        });
    }
}

En .NET 6, las rutas se pueden agregar directamente a WebApplication sin una llamada explícita a UseEndpoints o UseRouting. El código siguiente agrega un punto de conexión a un ASP.NET Core en la aplicación .NET 6:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Nota: Las rutas agregadas directamente a la WebApplication se ejecutan al final de la canalización.

Cambiar la raíz del contenido, el nombre de la aplicación y el entorno

ASP.NET Core en .NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseEnvironment(Environments.Staging)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>()
                      .UseSetting(WebHostDefaults.ApplicationKey,
                                  typeof(Program).Assembly.FullName);
        });

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    ApplicationName = typeof(Program).Assembly.FullName,
    ContentRootPath = Directory.GetCurrentDirectory(),
    EnvironmentName = Environments.Staging,
    WebRootPath = "customwwwroot"
});

Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}");
Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}");
Console.WriteLine($"WebRootPath: {builder.Environment.WebRootPath}");

var app = builder.Build();

Para obtener más información, consulte Información general de los conceptos básicos de ASP.NET Core.

Cambio de la raíz del contenido, el nombre de la aplicación y el entorno mediante variables de entorno o la línea de comandos

En la tabla siguiente se muestra la variable de entorno y el argumento de la línea de comandos usados para cambiar la raíz del contenido, el nombre de la aplicación y el entorno:

característica Variable del entorno Argumento de la línea de comandos
Nombre de la aplicación ASPNETCORE_APPLICATIONNAME --applicationName
Nombre del entorno ASPNETCORE_ENVIRONMENT --medio ambiente
Raíz del contenido ASPNETCORE_CONTENTROOT --contentRoot

Incorporación de proveedores de configuración

ASP.NET Core en .NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(config =>
        {
            config.AddIniFile("appsettings.ini");
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddIniFile("appsettings.ini");

var app = builder.Build();

Para obtener información detallada, vea Proveedores de configuración de archivos en Configuración en ASP.NET Core.

Adición de proveedores de registro

ASP.NET Core en .NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddJsonConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(args);

// Configure JSON logging to the console.
builder.Logging.AddJsonConsole();

var app = builder.Build();

Para obtener más información, consulte Registro en .NET Core y ASP.NET Core.

Agrega servicios

ASP.NET Core en .NET 5

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add the memory cache services
        services.AddMemoryCache();

        // Add a custom scoped service
        services.AddScoped<ITodoRepository, TodoRepository>();
    }
}

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(args);

// Add the memory cache services.
builder.Services.AddMemoryCache();

// Add a custom scoped service.
builder.Services.AddScoped<ITodoRepository, TodoRepository>();
var app = builder.Build();

Para más información, consulte Inserción de dependencias en ASP.NET Core.

Personalizar IHostBuilder o IWebHostBuilder

Personalizar IHostBuilder

ASP.NET Core en .NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(args);

// Wait 30 seconds for graceful shutdown.
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));

var app = builder.Build();

Personalizar IWebHostBuilder

ASP.NET Core en .NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            // Change the HTTP server implementation to be HTTP.sys based.
            webBuilder.UseHttpSys()
                      .UseStartup<Startup>();
        });

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(args);

// Change the HTTP server implementation to be HTTP.sys based.
// Windows only.
builder.WebHost.UseHttpSys();

var app = builder.Build();

Cambio de la raíz web

De forma predeterminada, la raíz web guarda relación con la raíz de contenido de la carpeta wwwroot. La raíz web es donde el middleware de archivos estáticos busca archivos estáticos. La raíz web se puede cambiar estableciendo la WebRootPath propiedad en WebApplicationOptions:

ASP.NET Core en .NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            // Look for static files in webroot.
            webBuilder.UseWebRoot("webroot")
                      .UseStartup<Startup>();
        });

ASP.NET Core en .NET 6

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    // Look for static files in webroot
    WebRootPath = "webroot"
});

var app = builder.Build();

Contenedor de inserción de dependencias (ID) personalizado

Los siguientes ejemplos de .NET 5 y .NET 6 usan Autofac

ASP.NET Core en .NET 5

Clase Program

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Arranque

public class Startup
{
    public void ConfigureContainer(ContainerBuilder containerBuilder)
    {
    }
}

ASP.NET Core en .NET 6

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<ContainerBuilder>(builder => builder.RegisterModule(new MyApplicationModule()));

var app = builder.Build();

Acceso a servicios adicionales

Startup.Configure puede insertar cualquier servicio agregado a través de IServiceCollection.

ASP.NET Core en .NET 5

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<IService, Service>();
    }

    // Anything added to the service collection can be injected into Configure.
    public void Configure(IApplicationBuilder app,
                          IWebHostEnvironment env,
                          IHostApplicationLifetime lifetime,
                          IService service,
                          ILogger<Startup> logger)
    {
        lifetime.ApplicationStarted.Register(() =>
            logger.LogInformation(
                "The application {Name} started in the injected {Service}",
                env.ApplicationName, service));
    }
}

ASP.NET Core en .NET 6

En ASP.NET Core en .NET 6:

  • Hay algunos servicios comunes disponibles como propiedades de nivel superior en WebApplication.
  • Es necesario resolver manualmente los servicios adicionales desde el IServiceProvider a través de WebApplication.Services.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IService, Service>();

var app = builder.Build();

IService service = app.Services.GetRequiredService<IService>();
ILogger logger = app.Logger;
IHostApplicationLifetime lifetime = app.Lifetime;
IWebHostEnvironment env = app.Environment;

lifetime.ApplicationStarted.Register(() =>
    logger.LogInformation(
        $"The application {env.ApplicationName} started" +
        $" with injected {service}"));

Prueba con WebApplicationFactory o TestServer

ASP.NET Core en .NET 5

En los ejemplos siguientes, el proyecto de prueba usa TestServer y WebApplicationFactory<TEntryPoint>. Estos paquetes se envían como paquetes independientes que requieren referencia explícita:

WebApplicationFactory

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="{Version}" />
</ItemGroup>

ServidorDePruebas

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="{Version}" />
</ItemGroup>

ASP.NET Core en código de .NET 5

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHelloService, HelloService>();
    }

    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);
            });
        });
    }
}

Con el TestServer

[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<WebApplication1.Startup>();
        })
        .ConfigureServices(services =>
        {
            // Replace the service
            services.AddSingleton<IHelloService, MockHelloService>();
        })
        .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";
}

Utilizando WebApplicationFactory

[Fact]
public async Task HelloWorld()
{
    var application = new WebApplicationFactory<Program>()
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                services.AddSingleton<IHelloService, MockHelloService>();
            });
        });

    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 en .NET 6


var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IHelloService, HelloService>();

var app = builder.Build();

var helloService = app.Services.GetRequiredService<IHelloService>();

app.MapGet("/", async context =>
{
    await context.Response.WriteAsync(helloService.HelloMessage);
});

app.Run();

Archivo de proyecto (.csproj)

El archivo de proyecto puede contener uno de los siguientes elementos:

<ItemGroup>
    <InternalsVisibleTo Include="MyTestProject" />
</ItemGroup>

O bien,

[assembly: InternalsVisibleTo("MyTestProject")]

Una solución alternativa consiste en hacer que la Program clase sea pública. Program se puede hacer público con declaraciones de nivel superior definiendo una public partial Program clase en el proyecto o en Program.cs:

var builder = WebApplication.CreateBuilder(args);

// ... Configure services, routes, etc.

app.Run();

public partial class Program { }
[Fact]
public async Task HelloWorld()
{
    var application = new WebApplicationFactory<Program>()
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                services.AddSingleton<IHelloService, MockHelloService>();
            });
        });

    var client = application.CreateClient();

    var response = await client.GetStringAsync("/");

    Assert.Equal("Test Hello", response);
}

class MockHelloService : IHelloService
{
    public string HelloMessage => "Test Hello";
}

La versión de .NET 5 y .NET 6 con WebApplicationFactory son idénticas por diseño.