Inyectando configuraciones en proyectos .NET
Tags: aspnet, aspdotnet, csharp, spanish
Published: 2023-08-23 04:09:03

La inyección de configuraciones en ASP.NET es un concepto fundamental que impulsa la flexibilidad y modularidad en el desarrollo de aplicaciones web. Tener la capacidad de ajustar el comportamiento de una aplicación sin necesidad de recompilar se ha vuelto esencial. Aquí es donde entra en juego la inyección de configuraciones.

En este contexto, este enfoque permite a los desarrolladores separar la configuración del código, lo que facilita la adaptación de la aplicación a diferentes entornos y escenarios, sin necesidad de modificar el código fuente. 

En este post, veremos distintas formas de conseguir las configuraciones que almacenamos en nuestro archivo **appsettings.json** para ver cual nos conviene más en dependencia de cada caso. En estos ejemplos estamos usando NET versión 6.

En nuestro archivo **appsettings.json** agregamos una nueva propiedad **CustomFields** que contiene las llaves con los valores que deseamos recuperar (Value1 y Value2)

```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "CustomFields": {
    "Value1": "this is value1",
    "Value2": "this is value2"
  }
}

```
También para nuestros ejemplos crearemos la interfaz a la cual llamé **IService** y **IService2** estas nos permitirá inyectar las instancias desde los cuales obtendremos las configuraciones y en la clase **CustomFields** en la retornaremos los valores que obtengamos desde el archivo de configuración.

```csharp
namespace ConfigurationInjection.Examples
{
    public interface IService
    {
        CustomFields GetConfiguration();
    }
    // Interfaz vacia que unicamente hereda de IService para luego 
    // poder inyectarlas implementando el método GetConfiguration
    public interface IService2 : IService { }

    public class CustomFields 
    {
        public string Value1 { get; set; }
        public string Value2 { get; set; }
    }
}
```

## Accediendo a través IConfiguration

Desde la versión de NET CORE 3.0, tenemos disponible por defecto la inyección de la configuración, este objeto nos permite acceder a las distintas propiedades definidas en **appsettings.json**.

```csharp
namespace ConfigurationInjection.Examples
{
    public class ByIConfiguration: IService
    {
        private readonly IConfiguration configuration;
        public ByIConfiguration(IConfiguration configuration)
        {
            this.configuration = configuration;
        }
        public CustomFields GetConfiguration() 
        {
            return new CustomFields
            {
                Value1 = configuration.GetSection("CustomFields")["Value1"],
                Value2 = configuration["CustomFields:Value1"]
            };
        }
    }
```

Puede observar ByIConfiguration implementa la interfáz IService, como se mencionó anteriormente esto es unicamente para poder inyectar ByIConfiguration donde lo necesitemos, luego inyectamos por contructor la implementación de IConfiguration.

Teniendo el configurations inyectado podemos acceder a las llaves mediante el método **GetSection("NombreSección")["NombreDeLlave"]** que obtiene un sección especifica o a través de la notación **["NombreSección:NombreDeLlave"]**

Para poder testiar realizaremos un cambio en el archivo **Program.cs** para inyectar **ByIConfiguration**


```csharp
builder.Services.AddSwaggerGen();

//Nueva linea para inyectar la clase que creamos
builder.Services.AddTransient<IService, ByIConfiguration>();

var app = builder.Build();

// Configure the HTTP request pipeline.
```

![Captura de configuraciones leídas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ctbisvkt8w4vhnwohzb.png)

## Usando IOptions<T>

A través de esta forma podremos acceder a configuraciones de una sección especifica, deberemos tener una clase que tenga las propiedades que queremos leer (los nombres deben ser los mismo sin tomar en cuenta mayúsculas o minúsculas) así, si queremos leer una llave como en este caso que se llama **Value1**, la propiedad se deberá llamar **Value1** o **value1**, también deberemos configurar en **Program.cs** lo siguiente.

```csharp
//Inyecta objeto ByIOptions
builder.Services.AddTransient<IService2, ByIOptions>();
//Estableciendo que sección de configuraciones se mapeara
builder.Services.Configure<CustomFields>(builder.Configuration.GetSection("CustomFields"));
```

Como puede ver establecemos que la clase que almacenará lo leído será **CustomFields** y que la sección que contiene las llaves a leer.


## Conclusión
En resumen, la inyección de configuraciones en ASP.NET es una técnica esencial que permite separar la configuración de una aplicación del código fuente, lo que proporciona una mayor flexibilidad y adaptabilidad en diferentes entornos y escenarios. En este artículo, hemos explorado cómo esta práctica es fundamental para ajustar el comportamiento de una aplicación sin necesidad de recompilar, lo que se ha vuelto crucial en el desarrollo de software actual.

A lo largo del artículo, hemos examinado diferentes enfoques para acceder a las configuraciones almacenadas en el archivo **appsettings.json**. Además, hemos destacado cómo a partir de la versión de .NET Core 3.0, se introdujo la inyección de dependencias predeterminada para IConfiguration, lo que facilita enormemente el acceso a las configuraciones desde distintos componentes de la aplicación.

Hemos visto ejemplos concretos utilizando IConfiguration y la interfaz IOptions para obtener y utilizar las configuraciones de manera eficiente. La opción de utilizar IOptions es especialmente atractiva cuando se trata de secciones con múltiples llaves, ya que nos permite mapear la configuración a objetos específicos y mantener un código más limpio y legible.

En resumen, la inyección de configuraciones no solo contribuye a una mejor organización de la aplicación, sino que también ayuda a mantener un código más modular, facilita las pruebas unitarias y mejora la escalabilidad. Al adoptar estas prácticas, los desarrolladores pueden lograr una arquitectura más robusta y flexible en sus aplicaciones ASP.NET.

Código fuente ejemplo en Github: [https://github.com/WestAMZ/ConfigurationInjection](https://github.com/WestAMZ/ConfigurationInjection)