TOC

This article has been localized into Spanish by the community.

Conceptos Básicos:

Opciones

En el artículo anterior, discutimos el mecanismo de Configuración de ".NET Core Framework". Este nos permite guardar las configuraciones de la aplicación en un archivo - por defecto en un archivo de formato JSON, pero puedes cambiar a otro formato si así lo deseas. Sin embargo, JSON es un excelente formato para almacenar configuraciones - es corto, conciso y rápido de analizar, al mismo tiempo que es fácil de leer y modificar para un humano.

En el artículo anterior, también vimos cuan fácil podíamos acceder a las configuraciones almacenadas en el archivo appsettings.json - usando llamadas a GetSection() y GetValue(), podíamos sacar las configuraciones basándonos en sus nombres (claves). Sin embargo, generalmente está mal visto confiar en en la especificación de un string cada vez que quieras acceder una propiedad: Si cambias el nombre del string en tu archivo de configuración, tendrás que modificar manualmente en todos los lugares en donde lo mencionas y como los strings no son verificados por el compilador, podrias olvidar cambiarlo en uno o más lugares, lo que haría fallar tu aplicación.

El patrón de Opciones

Como una alternativa, es recomendado usar el patron "Options" de "ASP.NET Core". Te permitirá crear clases con propiedades para contener tus opciones y el Framework creará automáticamente una instancia y poblará las clases para ti. Entonces, consideremos en ejemplo que vimos en el artículo anterior, donde almacenamos el título del sitio web en el archivo appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Title": "My ASP.NET Core MVC Website",    
}

Entonces podríamos crear una clase simple para esto:

public class WebsiteOptions
{
    public WebsiteOptions() { }

    public string Title { get; set; }
}

En el método ConfigureServices() del archivo Startup.cs, debemos decirle al Framework que use nuestra nueva clase. Para esto, necesitamos acceder a la interface IConfiguration, como se vio en el artículo anterior - será inyectado al principio de la clase en Startup.cs. Asegúrate de incluir el nombre de espacio Microsoft.Extensions.Configuration:

using Microsoft.Extensions.Configuration;

Luego modificamos la clase Startup en el archivo Startup.cs de la siguiente forma:

public class Startup
{
    private readonly IConfiguration _configuration;
    public Startup(IConfiguration configuration)
    {
_configuration = configuration;
    }

   
    public void ConfigureServices(IServiceCollection services)
    {
services.Configure<WebsiteOptions>(_configuration);
services.AddMvc();
    }
    ....

La línea interesante es la llamada a services.Configure(). Especificando nuestra clase de tipo (WebsiteOptions) y mencionando el miembro _configuration (el que fue inyectado en el constructor de Startup por el Framework) podemos conectar el archivo de configuración (appsettings.json) con nuestra clase WebsiteOptions.

Es tiempo de empezar a usar esas opciones. Está hecho como lo hicimos en el artículo anterior, donde pedimos que nuestras opciones de configuración se inyectaran en el lugar que necesitamos usarlas, p.ej. en el Controlador.

Usando la clase Opciones en el Controlador

Para acceder a las opciones desde el Controlador, asegúrate de que tiene un constructor como el siguiente:

....
using Microsoft.Extensions.Options;
using OptionsSample.Models;

public class HomeController : Controller    
{    
    private WebsiteOptions _websiteOptions;    
    public HomeController(IOptions<WebsiteOptions> websiteOptions)    
    {    
this._websiteOptions = websiteOptions.Value;    
    }  
    ....

Date cuenta de como usamos "Dependency Injection" nuevamente, esta vez pidiendo al Framework inyectar una instancia de la interface IOptions con nuestra clase WebsiteOptions como tipo. La instancia actual de WebsiteOptions estará contenida en la propiedad Valor de la interface IOptions, como se puede ver en el código. Entonces podremos asignarla a una variable local, permitiéndonos usarla en cualquier método dentro del Controlador, p.ej. el siguiente:

public IActionResult Index()
{
    return Content("Welcome to " + _websiteOptions.Title);
}

Muy simple!

Usando la clase Opciones desde la clase Startup

Algunas configuraciones son necesarias inmediatamente cuando tu aplicación comienza y como vimos en el artículo anterior, es posible accederlas desde la clase Startup. Esto también es cierto cuando se usa el patrón Opciones y el código es similar al que planteamos para el Controlador. En la clase Startup, usualmente operamos con dos métodos: ConfigureServices() y Configure(). Como inicializamos las Opciones en el método ConfigureServices(), ver mas arriba, y como el método es llamado antes de Configure(), podemos inyectarlas en el método Configure() y usar las opciones ahí:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<WebsiteOptions> optionsAccessor)
{
    string websiteTitle = optionsAccessor.Value.Title;
    ....

Como puedes ver, es muy similar a como son usadas en el Controlador.

Usando la clase Opciones desde una Vista

Si necesitas acceder a tus opciones directamente desde la Vista, pueden ser inyectadas de la misma manera que vimos en el artículo anterior. Aquí un ejemplo:

@using Microsoft.Extensions.Options
@inject IOptions<OptionsSample.Models.WebsiteOptions> OptionsAccessor

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

Welcome to @(OptionsAccessor.Value.Title)

Fíjate en la segunda línea como inyectamos la interface IOptions casi de la misma forma en que lo hicimos en el ejemplo anterior. También le dimos a la instancia un nombre (en este caso OptionsAccessor), al que podemos mencionar cuando necesitemos acceder a las opciones.

Secciones/Sub-Opciones

Para mantener las cosas simples, nuestro primer ejemplo demostró como puedes mantener una opción al alcance del archivo de configuración. Sin embargo, en una situación del mundo real, podrías crear una o varias secciones/sub-opciones en tu archivo de configuración. De hecho, el enfoque recomendado es tener una clase y una sección para cada grupo lógico de opciones que necesites en tu aplicación.

Así, en nuestra pequeña aplicación Demo, podríamos cambiar el archivo appsettings.json para agrupar las opciones relacionadas con nuestro sitio web, como sigue:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Website": {
    "Title": "My ASP.NET Core MVC Website",
    "Version": 1.01
  }  
}

Nuestra clase WebsiteOptions debería reflejar la nueva propiedad (Version):

public class WebsiteOptions
{
    public WebsiteOptions() { }

    public string Title { get; set; }

    public double Version { get; set; }
}

También necesitamos instruir al Framework sobre donde buscar esas opciones, entonces nuestra llamada a services.Configure() en Startup.cs necesita ser modificada. Usaremos el método GetSection() para solicitar una sección específica, la que se usará cuando se llene la instancia WebsiteOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<WebsiteOptions>(_configuration.GetSection("Website"));
    ....

El string que pasamos como parámetro al método GetSection() debería igualar la clave en el archivo de configuración - en este caso "Website".

Hecho esto, las opciones de nuestro sitio web tienen ahora su propia sección en el archivo de configuración. Puedes agregar mas secciones como estas, con la correspondiente clase Opciones.

La forma de acceder a las opciones es la misma, ya que estábamos accediendo a una instancia de la clase WebsiteOptions.

Sumario

Con una combinación del mecanismo de Configuración y el patron de Opciones de .NET Framework, podemos fácilmente almacenar y acceder a las configuraciones de la aplicación de una forma muy robusta en nuestra aplicación.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!