Creando secciones de configuración personalizadas con ConfigurationSection. Como mejorar y organizar los ficheros de configuración y los deployments.

Organizar los web.config o app.config, es una tarea que debería estar presente en cualquier ciclo de desarrollo de software. Lamentablemente no siempre se realizan estas tareas, ya que el Framework de ASP.NET, nos facilita una serie de mecanismos para que de una forma muy sencilla, podamos acceder y almacenar la configuración que necesitemos en un momento x.

Anteriormente hemos visto como usando ficheros de settings, podemos organizar nuestro web.config de una forma muy eficiente y sencilla, ahora vamos a ver algo un poquito más avanzado, pero igual de fácil.

.Net, a través de su Framework (desde la versión 2.0), nos facilita una serie de clases que nos permiten personalizar los ficheros de configuración en función de nuestras necesidades, permitiéndonos crear nuestras propias secciones dentro de la configuración de manera que el web.config o app.config nos va a quedar mucho más organizado y consolidado.

Así pues si estas cansado de almacenar la configuración de tu aplicación como una lista interminable de entradas en el nodo appSettings y quieres organizarlo un poquito, continua leyendo y vamos al asunto.

Creando la clase que encapsula el acceso a nuestra sección personalizada dentro de la configuración.

Lo primero que vamos a hacer es crear la clase que nos va a permitir encapsular el acceso a nuestra sección personalizada. Esta clase debe heredar de la clase ConfigurationSection del Framework y posteriormente vamos a ir creando una propiedad por cada ítem que se vaya a almacenar en la configuración.

La clase puede ser algo así:

public class BlogSettings : ConfigurationSection
{
}

Ahora nos toca crear las propiedades que nos encapsulen el acceso, vamos a ello:

[ConfigurationProperty(TITLE_PROPERTY_NAME, DefaultValue="A deshoras", IsRequired=true)]
public string Title
{
get
{
return (string)this[TITLE_PROPERTY_NAME];
}
}

Como veis, estas propiedades están marcadas como ConfigurationProperty, y además, le indicamos el nombre de la propiedad dentro de la configuración, el valor por defecto y si es requerida o no.

Creando un Manager que gestione nuestra clase de configuración.

Como queremos que esto quede de maravilla, vamos a crear un manager, este se tiene que encargar de automatizar el acceso a la sección de configuración personalizada (custom configuration section) y la modificación si es preciso.

Para realizar estas funciones, vamos a crear una clase estática, que como miembro, tendrá una instancia de la clase que anteriormente hemos creado.

El manager, será algo así:

public static class BlogSettingsManager
{
#region constants
private static string BLOG_SETTINGS_NODE_NAME = "BlogSettings";
#endregion
#region members
private static BlogSettings _settings = ConfigurationManager.GetSection(BLOG_SETTINGS_NODE_NAME) as BlogSettings;
#endregion
#region Properties
public static BlogSettings Settings
{
get { return _settings; }
}
#endregion
}

Creando nuestra sección personalizada (custom configuration section) dentro del web.config o app.config.

Y ya solo nos queda añadir nuestra sección personaliza al web.config o app.config. Para ello, tenemos que añadir un nodo section hijo del nodo configSections, y en este nodo, tenemos que indicar el nombre de nuestra sección, y el tipo, que no viene a ser otra cosa que el nombre de la clase con el namespace y el nombre de la dll donde tengamos la clase que va a gestionar esta configuración (en nuestro caso BlogSettings).

El código sería el siguiente:

<configuration>
<configSections>
<section name="BlogSettings" type="CustomConfigurationSection.Framework.BlogSettings, CustomConfigurationSection.Framework"/>
</configSections>
<BlogSettings Title="Adeshoras" NumberOfItemsPerPage="20" />
</configuration>

Ahora solo nos queda usarlo a lo largo de nuestra app, y esto amigos míos, es lo más sencillo de todo, sería un código del estilo al siguiente:

BlogSettingsManager.Settings.Title

Como siempre, te recomiendo que te bajes este código y lo veas en vivo y en directo, seguro que te maravilla.

Nada más, como podéis ver mis druguitos, de una forma muy sencilla podemos encapsular el acceso a nuestra configuración y además personalizar los ficheros donde almacenamos la susodicha configuración (en nuestro caso web.config o app.config). Esto es muy simple y elegante y con una funcionalidad de este tipo, los deployments serán más sencillos ya que tendremos mucho más organizados nuestros ficheros de configuración.

Mientras he escrito este post, he estado escuchando a los Misfits y ahora es vuestro turno.

El elemento clear para las appSettings y los deployments.

Desde hace unos días, he estado hablando del tema de los deployments centrándome sobre todo en la herencia de los web.config de nuestras aplicaciones (funcionalidad muy interesante y a tener en cuenta en todo momento).

Hay varias formas de sobrescribir esta herencia o de configurar nuestro web.config para que nuestra aplicación trabaje de una forma u otra, y hoy vamos a ver otro mecanismo.

Este mecanismo, no viene a ser otro que el elemento clear de las appSettings.

El elemento clear, quita todas las referencias de los appSettings de nuestra aplicación, y solo nos permite trabajar con la configuración agregada por el elemento add.

Usarlo es muy fácil:

<appSettings>
<clear />
<add key=”NumberOfItems” value=”20” />
</appSettings>

Útil y fácil como tienen que ser las cosas, ahora amigos, os dejo. Pero os dejo acompañados del fabuloso Bobby Womack y su genial Across 110th Street, inmortalizada por el no menos fabuloso y genial Tarantino en los títulos de crédito de Jackie Brown.

Deployments, web.config’s y archivos de settings.

Quien no se han encontrado con web.config’s que contienen una cantidad de appSettings que es inmanejable. Supongo que más o menos todos, ya que si no se tiene cuidado, estas appSettings pueden crecer de manera desmesurada complicando mucho los deployments y sobre todo haciendo que las susodichas settings pierdan su efectividad ya que se puede dar el caso de no saber para que se usa cada una (sobre todo si el proyecto lo tienes en producción desde hace n años).

El nodo appSettings, es muy útil ya que nos permite modificar valores que afectan al comportamiento de nuestra aplicación de una forma rápida y efectiva (y sin ser necesario compilar), pero estas como todo, hay que mantenerlas y sobre todo organizarlas.

Con asp.net 2.0, se introdujeron unos nuevos ficheros que nos permitían manejar la configuración de nuestra aplicación de una forma mucho más ordenada y efectiva.

Estos ficheros, eran los ficheros de settings, por medio de ellos, vamos a poder almacenar app settings y acceder a ellas de una forma enumerada. Además cuando creamos un fichero de settings, se genera una clase que nos va a serializar y deserializar de una forma automática y optima el acceso a nuestras settings.

Para crear un fichero de settings, puedes hacerlo de dos formas:

  • Btn derecho en nuestro proyecto -> Add ítem -> settings file  (en class libraries)
  • Btn derecho en nuestro proyecto -> properties -> settings (en proyectos web)

Una vez que tenemos el archivo creado, ya solo nos queda añadir nuestras settings, el tipo de dato que va a almacenar, el scope (user o application) y por último el valor que almacenan.

Estas settings, al igual que las appSettings, se almacenan en nuestro web.config o app.config, de esta forma, también las podemos modificar sin tener que volver a compilar nuestro proyecto.

Veamos un ejemplo, supongamos que trabajamos con las appSettings, yo defino n appSettings en mi proyecto, y para usarlas debería hacer algo por el estilo a esto:
private const string NUMBER_OF_ITEMS = "NumberOfItems";
public int NumberOfItems
{
get{ return Convert.ToInt32(WebConfigurationManager.AppSettings[NUMBER_OF_ITEMS]); }
}

Si utilizamos un archivo de settings, únicamente tendríamos que hacer lo siguiente:

Settings.DisplaySettings.Default.NumberOfITems;

Siendo Settings el namespace y UrlSettings, la clase que se va a generar para poder encapsular el acceso a la susodichas settings.
Si esto ya os ha gustado (que seguro que sí), lo mejor viene ahora, si trabajamos con nuestro nodo de appSettings, las settings las tenemos que definir más o menos de la siguiente forma:

Mientras que si trabajamos con este tipo de ficheros y aunque igualmente se almacenan en el web.config, se almacenan de la siguiente forma:


<TestSettings.Settings.AppGlobalSettings>

date

Como podéis ver mucho más ordenado y eficiente.

Como apunte deciros que la buena práctica recomienda el incluir estas settings y nodos en nuestro web.config o app.config principal, pero si no lo hacéis, esta clase que se autogenera al no encontrar el valor buscado, usa el valor que se le dio cuando se precompiló. Que esto sea una ventaja o inconveniente lo tiene que decidir cada uno, el hecho es que el asunto funciona así.

Recientemente, he implementado una aplicación Web. Esta app explota las API’s de varias redes sociales. Para almacenar la configuración necesaria de cada una de estas piezas he usado este tipo de archivos. Permiten trabajar de forma muy sencilla y todo queda más claro y ordenado cuando vas a hacer el deployment. Además, mejora muchísimo la matenibilidad y administración del software desarrollado y desplegado.

 

Como conseguir que no haya herencia en los web.config. El tag location.

Aunque recientemente hablaba de la herencia de los web.config como algo bueno y que tenemos que tener en cuenta cuando desarrollamos aplicaciones que van a ser ejecutadas en directorios virtuales dentro de Web Sites, esta característica, también nos puede suponer que nos encontremos con algunos problemas.

Así, pues, de forma muy sencilla, podemos “desactivar” la herencia de web.config (o directamente no heredar) consiguiendo de esta forma que cada aplicación, este siendo hospedada por medio de un Web Site o un Virtual Directory, tenga su propia configuración completa.

El tag del web.config location, nos va a permitir deshabilitar esta herencia por medio del atributo inheritInChildApplications.

Para usarlo, tendríamos que poner dentro los nodos del web.config a los que vamos a hacerles el wrapper.

<location path="." inheritInChildApplications="false">
<connectionStrings>
...
</connectionStrings>
<system.web>
...
</system.web>
</location>

Espero que este código os resulte útil. Cualquier comentario será bienvenido.

 

La herencia de los Web.config, los deployment y el tag remove

Anteriormente, hemos visto, que es útil y una buena práctica, el soportar la herencia de los web.config de tus apliaciones web.

Puede ser muy útil, tener un web.config padre y una serie de web.config hijos, donde se encapsule la configuración de cada una de tus aplicaciones ya que así los deployment y mantenimientos son más sencillos y sobre todo, así mantienes todas tus aplicaciones de una forma más compacta.

Eso si, siempre se pueden dar casos, donde nos encontremos que nuestro web.config esta herendado de otro, y el web.config padre, hace referencia a elementos que nos necesitamos, lo cual nos va a generar un problema, pero tranquilos, esto es muy fácil solucionarlo gracias al tag remove.

El tag remove, se va a encargar de “eliminar” las referencias del web.config que no necesitemos.

Un ejemplo de su uso sería el siguiente:

<httpModules>
<remove name="HttpExceptionHandlerPipeline" />
<remove name="HttpsSwitcherPipeline" />
<remove name="RedirectModule" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>

Sencillo y útil, como todo debería de ser.

La herencia de web.config y los deployment.

Es interesante ver como por norma general e independientemente del paso del tiempo, los deployment han sido y son tareas que sin tener porque, se complican y llegan a rayar lo absurdo.

Generalmente cuando estamos en un proyecto, disponemos de distintos entornos, conforme vamos avanzando en el ciclo de vida del desarrollo del software, vamos desplegando la aplicación en el entorno de desarrollo, preproducción etc. y en el momento que tenemos que poner la aplicación en producción siempre surge alguna cosa.

Si el proyecto en el que nos encontramos trabajando es muy grande, es una buena práctica partirlo en porciones más pequeñas, así podemos trabajar de una forma más desacoplada y posteriormente el deployment también podemos conseguir que sea más sencillo.

Supongamos que estamos en un proyecto que es muy grande, y que en este momento, estas desarrollando pequeñas piezas, que sin formar parte del core del negocio que intenta resolver, lo complementa.

Una buena solución es trabajar en distintas soluciones de manera que una funcionalidad x la tienes totalmente encapsulada en la solución que le corresponde. Y así, cuando llega el momento de hacer el deployment, puedes desplegar el core de tu negocio en un Web Site, y todas las aplicaciones satélites pueden ser virtual directories dentro de tu web site principal.

A la hora de hacer el deployment, cuando tenemos un Web Site que contiene n directorios virtuales, podemos observar como el web.config de los directorios virtuales, heredan del web.config del Web Site, de esta manera, puedes dejar toda la configuración común de tu app en el web.config de la aplicación que implementa el core de tu negocio, y toda la configuración de tus aplicaciones satélites en el web.config de cada una de ellas (en su respectivo virtual directory), así consigues tener la configuración de cada pieza aislada y más controlada.

Seguramente esta práctica, genera un trabajo de configuración y mantenimiento mayor, pero merece la pena por el hecho de tener todo más aislado y desacoplado.