Arquitectura de configuración de la aplicación

Este tema describe cómo funciona la arquitectura de la configuración de la aplicación y explora las características avanzadas de la arquitectura, como valores de configuración agrupados y claves de configuración.

La arquitectura de configuración de la aplicación admite la definición de parámetros de configuración fuertemente tipados tanto de ámbito de aplicación como de usuario, así como la conservación de dichos parámetros entre las sesiones de la aplicación. La arquitectura proporciona un motor de persistencia predeterminado para guardar la configuración en el sistema de archivos local y cargarla después desde este. La arquitectura también define las interfaces para proporcionar un motor de persistencia personalizado.

Las interfaces se proporcionan para habilitar los componentes personalizados con el fin de que conserven su propia configuración cuando se hospedan en una aplicación. Mediante el uso de claves de configuración, los componentes pueden conservar la configuración para varias instancias del componente independiente.

Definir la configuración

La arquitectura de configuración de la aplicación se utiliza en ASP.NET y en Windows Forms, y contiene un número de clases base que comparten ambos entornos. La más importante es SettingsBase, que proporciona el acceso a la configuración a través de una colección y proporciona los métodos de bajo nivel para cargar y guardar la configuración. Cada entorno implementa su propia clase derivada de SettingsBase para proporcionar la funcionalidad de la configuración adicional para ese entorno. En una aplicación basada en Windows Forms, toda la configuración de la aplicación debe definirse en una clase derivada de ApplicationSettingsBase, que agrega la siguiente funcionalidad a la clase base:

  • Operaciones de almacenamiento y de carga de nivel superior

  • Compatibilidad de la configuración de ámbito de usuario

  • Revertir la configuración de un usuario a los valores predeterminados

  • Actualizar la configuración de una versión de aplicación anterior

  • Validar la configuración antes de modificarla o después de guardarla

La configuración se puede describir utilizando varios atributos definidos dentro del espacio de nombres System.Configuration; estos se describen en Atributos de configuración de la aplicación. Cuando se define un valor de configuración, debe aplicarse con ApplicationScopedSettingAttribute o UserScopedSettingAttribute, que especifican si la configuración se aplica a toda la aplicación o solo para el usuario actual.

En el ejemplo de código siguiente se define una clase de configuración personalizada con una configuración única, BackgroundColor.

using System;
using System.Configuration;
using System.Drawing;

public class MyUserSettings : ApplicationSettingsBase
{
    [UserScopedSetting()]
    [DefaultSettingValue("white")]
    public Color BackgroundColor
    {
        get
        {
            return ((Color)this["BackgroundColor"]);
        }
        set
        {
            this["BackgroundColor"] = (Color)value;
        }
    }
}
Imports System.Configuration

Public Class MyUserSettings
    Inherits ApplicationSettingsBase
    <UserScopedSetting()> _
    <DefaultSettingValue("white")> _
    Public Property BackgroundColor() As Color
        Get
            BackgroundColor = Me("BackgroundColor")
        End Get

        Set(ByVal value As Color)
            Me("BackgroundColor") = value
        End Set
    End Property
End Class

Conservar la configuración

La clase ApplicationSettingsBase no se conserva ni carga la configuración; este trabajo lo realiza el proveedor de configuración, una clase que deriva de SettingsProvider. Si una clase derivada de ApplicationSettingsBase no especifica un proveedor de configuración a través de SettingsProviderAttribute, entonces debe utilizar el proveedor predeterminado LocalFileSettingsProvider.

El sistema de configuración incluido originalmente en .NET Framework admite proporcionar datos de configuración de la aplicación estáticos mediante un archivo machine.config del equipo local o dentro de un archivo app.exe.config que implemente con su aplicación. La clase LocalFileSettingsProvider expande esta compatibilidad nativa de las siguientes formas:

  • La configuración de ámbito de aplicación se puede almacenar en los archivos machine.config o app..exe.config. Machine.config siempre es de solo lectura, mientras que app.exe.config está restringido por razones de seguridad a solo lectura para la mayoría de las aplicaciones.

  • La configuración de ámbito de usuario se puede almacenar en archivos app.exe.config, en cuyo caso se tratan como valores predeterminados estáticos.

  • La configuración de ámbito de usuario no predeterminada se almacena en un nuevo archivo: user.config. Puede especificar un valor predeterminado para una configuración de ámbito de usuario con DefaultSettingValueAttribute. Puesto que la configuración de ámbito de usuario cambia a menudo durante la ejecución de la aplicación, user.config siempre es de lectura y escritura. Para obtener más información, consulte ¿Dónde se almacena la configuración de ámbito de usuario?

Los tres archivos de configuración almacenan la configuración en formato XML. El elemento XML de nivel superior para la configuración de ámbito de la aplicación es <appSettings>, mientras que <userSettings> se utiliza para la configuración de ámbito de usuario. Un archivo app.exe.config que contiene la configuración de ámbito de la aplicación y los valores predeterminados para la configuración de ámbito de usuario tendría el siguiente aspecto:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="WindowsApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </sectionGroup>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="WindowsApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" />
        </sectionGroup>
    </configSections>
    <applicationSettings>
        <WindowsApplication1.Properties.Settings>
            <setting name="Cursor" serializeAs="String">
                <value>Default</value>
            </setting>
            <setting name="DoubleBuffering" serializeAs="String">
                <value>False</value>
            </setting>
        </WindowsApplication1.Properties.Settings>
    </applicationSettings>
    <userSettings>
        <WindowsApplication1.Properties.Settings>
            <setting name="FormTitle" serializeAs="String">
                <value>Form1</value>
            </setting>
            <setting name="FormSize" serializeAs="String">
                <value>595, 536</value>
            </setting>
        </WindowsApplication1.Properties.Settings>
    </userSettings>
</configuration>

Para obtener una definición de los elementos incluidos en la sección de configuración de aplicación de un archivo de configuración, consulte Esquema de la configuración de la aplicación.

Enlaces de configuración

La configuración de aplicación utiliza la arquitectura de enlace de datos de Windows Forms para proporcionar una comunicación bidireccional de actualizaciones de parámetros de configuración entre el objeto de configuración y los componentes. Si utiliza Visual Studio para crear configuraciones de aplicación y asignarlas a las propiedades de componente, estos enlaces se generarán automáticamente.

Solo puede enlazar una configuración de aplicación a un componente que admita la interfaz IBindableComponent. A su vez, el componente debe implementar un evento de cambio para una propiedad enlazada específica, o notificar a la configuración que la propiedad ha cambiado a través de la interfaz INotifyPropertyChanged. Si el componente no implementa IBindableComponent y usted enlaza a través de Visual Studio, las propiedades enlazadas se establecerán la primera vez, pero no se actualizarán. Si el componente implementa IBindableComponent pero no admite las notificaciones de cambio de propiedades, el enlace no se actualizará en el archivo de configuración cuando cambie la propiedad.

Algunos componentes de Windows Forms, como ToolStripItem, no admiten enlaces de configuración.

Serialización de la configuración

Cuando LocalFileSettingsProvider debe guardar la configuración en el disco, realiza las acciones siguientes:

  1. Utiliza la reflexión para examinar todas las propiedades definidas en su clase derivada ApplicationSettingsBase, y encuentra aquellas que se aplican con ApplicationScopedSettingAttribute o UserScopedSettingAttribute.

  2. Serializa la propiedad en el disco. Primero, intenta llamar a ConvertToString o ConvertFromString en el TypeConverter asociado del tipo. Si esto no tiene éxito, en su lugar utiliza la serialización XML.

  3. Determina qué configuración corresponde a cada archivo, basándose en el atributo de la configuración.

Si implementa su propia clase de configuración, puede usar SettingsSerializeAsAttribute para marcar una configuración para una serialización binaria o personalizada mediante la enumeración SettingsSerializeAs. Para más información sobre cómo crear su propia clase de parámetros de configuración en código, vea How to: Create Application Settings (Creación de la configuración de la aplicación).

Ubicaciones del archivo de configuración

La ubicación de los archivos app.exe.config y usuario.config diferirá según cómo se instale la aplicación. Para una aplicación basada en Windows Forms copiada en el equipo local, app.exe.config residirá en el mismo directorio que el directorio base del archivo ejecutable principal de la aplicación, y el archivo usuario.config residirá en la ubicación especificada por la propiedad Application.LocalUserAppDataPath. Para una aplicación instalada mediante ClickOnce, los dos archivos residirán en el directorio de datos de ClickOnce en %InstallRoot%\Documents and SettingsnombreDeUsuario\Local Settings.

La ubicación de almacenamiento de estos archivos es diferente si un usuario habilita perfiles móviles, lo que permite a dicho usuario definir diferentes configuraciones de aplicación y de Windows cuando utilice otros equipos dentro de un dominio. En ese caso, tanto las aplicaciones de ClickOnce como las que no sean de ClickOnce tendrán archivos app.exe.config y usuario.config almacenados en %InstallRoot%\Documents and SettingsnombreDeUsuario\Application Data.

Para más información sobre cómo funciona la característica Configuración de la aplicación con la nueva tecnología de implementación, vea ClickOnce y configuración de la aplicación. Para más información sobre el directorio de datos de ClickOnce, vea Obtener acceso local o remoto a los datos en aplicaciones ClickOnce.

Configuración de la aplicación y seguridad

La configuración de la aplicación está diseñada para trabajar con confianza parcial, un entorno restringido predeterminado en las aplicaciones de Windows Forms hospedadas en la intranet y en Internet. No es necesario ningún permiso especial más allá de la confianza parcial para utilizar la configuración de la aplicación con el proveedor de configuración predeterminado.

Cuando los parámetros de configuración de la aplicación se utilizan en una aplicación de ClickOnce, el archivo user.config se almacena en el directorio de datos de ClickOnce. El tamaño del archivo user.config de la aplicación no puede superar la cuota de directorio de datos establecida por ClickOnce. Para más información, consulte ClickOnce y configuración de la aplicación.

Proveedores de configuración personalizados

En la arquitectura de la configuración de la aplicación, existe una correspondencia imprecisa entre la clase contenedora de la configuración de la aplicación, derivada de ApplicationSettingsBase, y el proveedor o proveedores de los valores de configuración asociados, derivados de SettingsProvider. Esta asociación está definida solo por la clase SettingsProviderAttribute aplicada a la clase contenedora o a sus propiedades individuales. Si no se especifica un proveedor de valores de configuración, se utiliza el proveedor predeterminado LocalFileSettingsProvider. Como resultado, esta arquitectura admite la creación y el uso de proveedores de valores de configuración personalizados.

Por ejemplo, suponga que desea desarrollar y utilizar SqlSettingsProvider, un proveedor que almacenará todos los valores de configuración en una base de datos de Microsoft SQL Server. La clase derivada de SettingsProvider recibiría esta información en su método Initialize como un parámetro de tipo System.Collections.Specialized.NameValueCollection. A continuación implementaría el método GetPropertyValues para recuperar la configuración del almacén de datos y SetPropertyValues para guardarla. El proveedor puede usar SettingsPropertyCollection que se proporciona a GetPropertyValues para determinar el nombre de la propiedad, el tipo y el ámbito, así como cualquier otro atributo de configuración definido para esa propiedad.

El proveedor necesitará implementar una propiedad y un método cuyas implementaciones pueden no ser evidentes. La propiedad ApplicationName es una propiedad abstracta de SettingsProvider; debería programarla para devolver lo siguiente:

public override string ApplicationName
{
    get
    {
        return (System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
    }
    set
    {
        // Do nothing.
    }
}
Public Overrides Property ApplicationName() As String
    Get
        ApplicationName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
    End Get
    Set(ByVal value As String)
        ' Do nothing.
    End Set
End Property

Su clase derivada también debe implementar un método Initialize que no toma ningún argumento y no devuelve ningún valor. Este método no está definido por SettingsProvider.

Finalmente, implemente IApplicationSettingsProvider en el proveedor para proporcionar compatibilidad con la actualización de la configuración, revertiendo la configuración a los predeterminados y actualizándola de una versión de la aplicación a otra.

Una vez implementado y compilado su proveedor, es necesario indicar a su clase de configuración que debe utilizar este proveedor en lugar del predeterminado. Puede hacerlo a través de SettingsProviderAttribute. Si se aplica a una clase de configuración completa, se utiliza el proveedor para cada configuración que defina la clase; si se aplica a configuraciones independientes, la arquitectura de la Configuración de la aplicación solo utiliza ese proveedor para esas configuraciones concretas y LocalFileSettingsProvider para el resto. El ejemplo de código siguiente muestra cómo indicar a la clase de configuración que utilice su proveedor personalizado.

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace ApplicationSettingsArchitectureCS
{
    [SettingsProvider("SqlSettingsProvider")]
    class CustomSettings : ApplicationSettingsBase
    {
        // Implementation goes here.
    }
}
Imports System.Configuration

<SettingsProvider("SqlSettingsProvider")> _
Public Class CustomSettings
    Inherits ApplicationSettingsBase

    ' Implementation goes here.
End Class

Se puede llamar a un proveedor simultáneamente desde varios subprocesos, pero siempre se escribe en la misma ubicación de almacenamiento; por tanto, la arquitectura de la Configuración de la aplicación solo creará una única instancia de la clase del proveedor.

Importante

Debería asegurarse de que su proveedor es seguro para subprocesos y que solo permite un subproceso al mismo tiempo que escribe en los archivos de configuración.

El proveedor no necesita ser compatible con todos los atributos de configuración definidos en el espacio de nombres System.Configuration, aunque debe existir un mínimo de compatibilidad con ApplicationScopedSettingAttribute y UserScopedSettingAttribute, y también debería ser compatible con DefaultSettingValueAttribute. Para esos atributos que no admite, el proveedor solo debería enviar un mensaje de error sin notificación, no producir una excepción. Si la clase de configuración utiliza una combinación de atributos no válida, como aplicar ApplicationScopedSettingAttribute y UserScopedSettingAttribute al mismo valor de configuración, el proveedor debería iniciar una excepción y detenerse.

Consulte también