Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 14 de febrero de 2017
ASP.NET CoreHace algunos meses comentábamos por aquí cómo en ASP.NET Core es posible modificar los archivos de configuración de una aplicación en caliente, sin necesidad de detenerla, siendo los cambios aplicados de forma inmediata.

En aquél momento ya vimos que era realmente sencillo conseguirlo cuando usábamos settings no tipados, bastaba con añadir el parámetro reloadOnChanges a la hora de añadir el origen de configuración, como en el siguiente ejemplo:
public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}
Sin embargo, también vimos que conseguir lo mismo cuando queríamos acceder a los settings de forma tipada era algo más engorroso, puesto que había que configurar manualmente el proceso de recarga y bindeado de datos con la instancia de la clase de configuración, para poder acceder luego a ella a través de un objeto IOptions<T> disponible en el contenedor de dependencias.

Pues bien, en ASP.NET Core 1.1, la cosa se ha simplificado bastante :) Vamos a ver paso a paso cómo acceder de forma tipada a los settings almacenados en un archivo JSON, y que éstos se refresquen automáticamente cuando el archivo de configuración sea modificado.

1. Añadimos al raíz del proyecto un archivo de configuración, al que llamamos por ejemplo MySettings.json, e introducimos un contenido como el siguiente. Observad que podemos estructurar los settings como más nos convenga:
{
  "AppTitle": "Settings demo",
  "Author": {
    "Name": "John Smith",
    "Age": 99
  }
}
2. En el constructor de la clase Startup, creamos un objeto de configuración añadiendo el archivo JSON como origen, indicando que debe recargar automáticamente mediante el parámetro reloadOnChanges:
public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("mysettings.json", optional: false, reloadOnChange: true)
            ... // Other setting sources
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }
    ...
}
3. Creamos una clase cuya estructura coincida con la de los settings a los que queremos acceder de forma tipada, por ejemplo como la que sigue. Aseguraos de que los nombres de las propiedades coincidan con los usados en el archivo de configuración:
public class MySettings 
{
   public string AppTitle { get; set; }
   public AuthorInfo Author { get; set; }

   public class AuthorInfo
   {
       public string Name { get; set; }
       public int Age { get; set; }
   }
}
4. En ConfigureServices() configuramos la instancia de la clase de settings en el contenedor de dependencias, asociándola al objeto de configuración que hemos creado anteriormente:
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    ... // Other services
    services.Configure<MySettings>(Configuration);
}
Como podréis comprobar, no hay nada nuevo en lo que hemos hecho hasta el momento. En versiones de ASP.NET Core anteriores a la 1.1 eran exactamente los pasos que debíamos seguir para tener nuestra instancia tipada disponible a través de instancias IOptions<T> obtenidas a través del inyector de dependencias. La novedad viene ahora ;)

5. Para acceder a los datos de configuración siempre frescos lo hacemos a través de una instancia de IOptionsSnapshot<T>, como en el siguiente ejemplo:
public class TestController : Controller
{
    private readonly MySettings _settings;

    public TestController(IOptionsSnapshot<MySettings> settings)
    {
        _settings = settings.Value;
    }
    public IActionResult Index()
    {
        var message =  $"{_settings.AppTitle}, " +
                       $"created by {_settings.Author.Name} " +
                       $"({_settings.Author.Age} years old)";

        return Content(message);
    }
}
Observad que el único cambio respecto a las versiones anteriores es que el acceso a la instancia de la clase de settings tipada lo hacemos solicitando un IOptionsSnapshot<T> en lugar de usar IOptions<T>.

Tras esto, si ejecutamos la aplicación, veremos que las modificaciones al archivo de configuración son tenidas en cuenta sobre la marcha, mostrándose en cada acceso a /test los valores actualizados.

Publicado en Variable not found.

Aún no hay comentarios, ¡sé el primero!