Inserción de dependencias en controladores en ASP.NET Core

Por Shadi Alnamrouti y Rick Anderson

Los controladores de ASP.NET Core MVC solicitan las dependencias de forma explícita a través de constructores. ASP.NET Core tiene compatibilidad integrada con la inserción de dependencias. La inserción de dependencias facilita las pruebas y el mantenimiento de las aplicaciones.

Vea o descargue el código de ejemplo (cómo descargarlo)

Inserción de constructores

Los servicios se agregan como un parámetro de constructor y el runtime resuelve el servicio desde el contenedor de servicios. Normalmente, los servicios se definen mediante interfaces. Por ejemplo, considere una aplicación que requiere la hora actual. En la interfaz siguiente se expone el servicio IDateTime:

public interface IDateTime
{
    DateTime Now { get; }
}

En el código siguiente se implementa la interfaz IDateTime:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Agregue el servicio al contenedor de servicios:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddControllersWithViews();
}

Para más información sobre AddSingleton, vea Duraciones de servicio de DI.

En el código siguiente se muestra un saludo al usuario según la hora del día:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Ejecute la aplicación y se mostrará un mensaje en función de la hora.

Inserción de acción con FromServices

FromServicesAttribute permite la inserción de un servicio directamente en un método de acción sin usar la inserción de constructores:

public IActionResult About([FromServices] IDateTime dateTime)
{
    return Content( $"Current server time: {dateTime.Now}");
}

Inserción de acción con FromKeyedServices

En el código siguiente se muestra cómo acceder a los servicios con claves desde el contenedor de inserción de dependencias mediante el atributo [FromKeyedServices]:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.Run();

public interface ICache
{
    object Get(string key);
}
public class BigCache : ICache
{
    public object Get(string key) => $"Resolving {key} from big cache.";
}

public class SmallCache : ICache
{
    public object Get(string key) => $"Resolving {key} from small cache.";
}

[ApiController]
[Route("/cache")]
public class CustomServicesApiController : Controller
{
    [HttpGet("big")]
    public ActionResult<object> GetBigCache([FromKeyedServices("big")] ICache cache)
    {
        return cache.Get("data-mvc");
    }

    [HttpGet("small")]
    public ActionResult<object> GetSmallCache([FromKeyedServices("small")] ICache cache)
    {
        return cache.Get("data-mvc");
    }
}

Acceso a la configuración desde un controlador

El acceso a la configuración de la aplicación o a los valores de configuración desde un controlador es un patrón habitual. El patrón de opciones que se describe en Patrón de opciones en ASP.NET Core es el enfoque preferido para administrar la configuración. Por lo general, IConfiguration no se inserta directamente en un controlador.

Cree una clase que represente las opciones. Por ejemplo:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Agregue la clase de configuración a la colección de servicios:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);

    services.AddControllersWithViews();
}

Configure la aplicación para leer la configuración de un archivo con formato JSON:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("samplewebsettings.json",
                    optional: false,
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

En el código siguiente se solicita la configuración IOptions<SampleWebSettings> del contenedor de servicios y se usa en el método Index:

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Recursos adicionales

Por Shadi Alnamrouti, Rick Anderson y Steve Smith

Los controladores de ASP.NET Core MVC solicitan las dependencias de forma explícita a través de constructores. ASP.NET Core tiene compatibilidad integrada con la inserción de dependencias. La inserción de dependencias facilita las pruebas y el mantenimiento de las aplicaciones.

Vea o descargue el código de ejemplo (cómo descargarlo)

Inserción de constructores

Los servicios se agregan como un parámetro de constructor y el runtime resuelve el servicio desde el contenedor de servicios. Normalmente, los servicios se definen mediante interfaces. Por ejemplo, considere una aplicación que requiere la hora actual. En la interfaz siguiente se expone el servicio IDateTime:

public interface IDateTime
{
    DateTime Now { get; }
}

En el código siguiente se implementa la interfaz IDateTime:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Agregue el servicio al contenedor de servicios:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddControllersWithViews();
}

Para más información sobre AddSingleton, vea Duraciones de servicio de DI.

En el código siguiente se muestra un saludo al usuario según la hora del día:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Ejecute la aplicación y se mostrará un mensaje en función de la hora.

Inserción de acción con FromServices

FromServicesAttribute permite la inserción de un servicio directamente en un método de acción sin usar la inserción de constructores:

public IActionResult About([FromServices] IDateTime dateTime)
{
    return Content( $"Current server time: {dateTime.Now}");
}

Acceso a la configuración desde un controlador

El acceso a la configuración de la aplicación o a los valores de configuración desde un controlador es un patrón habitual. El patrón de opciones que se describe en Patrón de opciones en ASP.NET Core es el enfoque preferido para administrar la configuración. Por lo general, IConfiguration no se inserta directamente en un controlador.

Cree una clase que represente las opciones. Por ejemplo:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Agregue la clase de configuración a la colección de servicios:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);

    services.AddControllersWithViews();
}

Configure la aplicación para leer la configuración de un archivo con formato JSON:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("samplewebsettings.json",
                    optional: false,
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

En el código siguiente se solicita la configuración IOptions<SampleWebSettings> del contenedor de servicios y se usa en el método Index:

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Recursos adicionales

Por Shadi Namrouti, Rick Anderson y Steve Smith

Los controladores de ASP.NET Core MVC solicitan las dependencias de forma explícita a través de constructores. ASP.NET Core tiene compatibilidad integrada con la inserción de dependencias. La inserción de dependencias facilita las pruebas y el mantenimiento de las aplicaciones.

Vea o descargue el código de ejemplo (cómo descargarlo)

Inserción de constructores

Los servicios se agregan como un parámetro de constructor y el runtime resuelve el servicio desde el contenedor de servicios. Normalmente, los servicios se definen mediante interfaces. Por ejemplo, considere una aplicación que requiere la hora actual. En la interfaz siguiente se expone el servicio IDateTime:

public interface IDateTime
{
    DateTime Now { get; }
}

En el código siguiente se implementa la interfaz IDateTime:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Agregue el servicio al contenedor de servicios:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Para más información sobre AddSingleton, vea Duraciones de servicio de DI.

En el código siguiente se muestra un saludo al usuario según la hora del día:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Ejecute la aplicación y se mostrará un mensaje en función de la hora.

Inserción de acción con FromServices

FromServicesAttribute permite la inserción de un servicio directamente en un método de acción sin usar la inserción de constructores:

public IActionResult About([FromServices] IDateTime dateTime)
{
    ViewData["Message"] = $"Current server time: {dateTime.Now}";

    return View();
}

Acceso a la configuración desde un controlador

El acceso a la configuración de la aplicación o a los valores de configuración desde un controlador es un patrón habitual. El patrón de opciones que se describe en Patrón de opciones en ASP.NET Core es el enfoque preferido para administrar la configuración. Por lo general, IConfiguration no se inserta directamente en un controlador.

Cree una clase que represente las opciones. Por ejemplo:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Agregue la clase de configuración a la colección de servicios:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);
    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Configure la aplicación para leer la configuración de un archivo con formato JSON:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile("samplewebsettings.json", 
                                optional: false,        // File is not optional.
                                reloadOnChange: false);
        })
        .UseStartup<Startup>();
}

En el código siguiente se solicita la configuración IOptions<SampleWebSettings> del contenedor de servicios y se usa en el método Index:

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Recursos adicionales