Compartilhar via


Arquitetura de configurações de aplicativo

Este tópico descreve como funciona a arquitetura de Configurações de Aplicativo e explora recursos avançados da arquitetura, como configurações agrupadas e chaves de configuração.

A arquitetura de configurações do aplicativo oferece suporte à definição de configurações fortemente tipadas com escopo de aplicativo ou de usuário, além da persistência dessas configurações entre as sessões do aplicativo. A arquitetura fornece um mecanismo de persistência padrão para salvar as configurações e carregá-las do sistema de arquivos local. A arquitetura também define interfaces para fornecer um mecanismo de persistência personalizado.

As interfaces são fornecidas que permitem que os componentes personalizados persistam suas próprias configurações quando são hospedados em um aplicativo. Usando chaves de configuração, os componentes podem manter as configurações para várias instâncias do componente separadas.

Definindo configurações

A arquitetura de configurações do aplicativo é usada no ASP.NET e no Windows Forms e contém várias classes base compartilhadas em ambos os ambientes. O mais importante é SettingsBase, que fornece acesso às configurações por meio de uma coleção e fornece métodos de baixo nível para carregar e salvar configurações. Cada ambiente implementa sua própria classe derivada de SettingsBase para fornecer funcionalidade de configurações adicionais para esse ambiente. Em um aplicativo baseado em Windows Forms, todas as configurações de aplicativo devem ser definidas em uma classe derivada da classe ApplicationSettingsBase, que adiciona a seguinte funcionalidade à classe base:

  • Operações de carregamento e salvamento de nível superior

  • Suporte para configurações do usuário

  • Revertendo as configurações de um usuário para os padrões predefinidos

  • Atualizando as configurações de uma versão anterior do aplicativo

  • Validando as configurações antes de serem alteradas ou antes de serem salvas

As configurações podem ser descritas usando vários atributos definidos no namespace System.Configuration; eles são descritos em atributos de configurações de aplicativo. Ao definir uma configuração, você deve aplicá-la com ApplicationScopedSettingAttribute ou UserScopedSettingAttribute, que descreve se a configuração se aplica a todo o aplicativo ou apenas ao usuário atual.

O exemplo de código a seguir define uma classe de configurações personalizadas com uma única configuração, 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

Persistência de configurações

A classe ApplicationSettingsBase em si não persiste ou carrega configurações; esse trabalho se enquadra no provedor de configurações, uma classe que deriva de SettingsProvider. Se uma classe derivada de ApplicationSettingsBase não especificar um provedor de configurações por meio do SettingsProviderAttribute, o provedor padrão, LocalFileSettingsProvider, será usado.

O sistema de configuração que foi originalmente lançado com o .NET Framework dá suporte ao fornecimento de dados de configuração de aplicativo estático por meio do arquivo machine.config do computador local ou em um arquivo app.exe.config que você implanta com seu aplicativo. A classe LocalFileSettingsProvider expande esse suporte nativo das seguintes maneiras:

  • As configurações no escopo do aplicativo podem ser armazenadas nos arquivos machine.config ou app.exe.config. Machine.config é sempre somente leitura, ao passo que app.exe.config é restrito a somente leitura para a maioria dos aplicativos, devido a considerações de segurança.

  • As configurações com escopo do usuário podem ser armazenadas em arquivos app.exe.config, nesse caso, elas são tratadas como padrões estáticos.

  • As configurações com escopo de usuário não padrão são armazenadas em um novo arquivo, user.config. Você pode especificar um padrão para uma configuração com escopo de usuário com DefaultSettingValueAttribute. Como as configurações com escopo do usuário geralmente mudam durante a execução do aplicativo, user.config está sempre em modo leitura e gravação. Para obter mais informações, consulte Onde estão armazenadas as configurações específicas do usuário.

Todos os três arquivos de configuração armazenam as configurações no formato XML. O elemento XML de nível superior para configurações com escopo de aplicativo é <appSettings>, enquanto <userSettings> é usado para configurações com escopo do usuário. Um arquivo app.exe.config que contém configurações com escopo de aplicativo e padrões para configurações com escopo de usuário teria esta aparência:

<?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 obter uma definição dos elementos na seção de configurações do aplicativo de um arquivo de configuração, consulte Esquema de Configurações do Aplicativo.

Vinculações de Configurações

As configurações de aplicativo usam a arquitetura de associação de dados do Windows Forms para fornecer comunicação bidirecional de atualizações de configurações entre o objeto de configurações e os componentes. Se você usar o Visual Studio para criar configurações de aplicativo e atribuí-las às propriedades do componente, essas associações serão geradas automaticamente.

Você só pode associar uma configuração de aplicativo a um componente que dê suporte à interface IBindableComponent. Além disso, o componente deve implementar um evento de alteração para uma propriedade associada específica ou notificar as configurações do aplicativo de que a propriedade foi alterada por meio da interface INotifyPropertyChanged. Se o componente não implementar IBindableComponent e você estiver associando por meio do Visual Studio, as propriedades associadas serão definidas pela primeira vez, mas não serão atualizadas. Se o componente implementar IBindableComponent mas não oferecer suporte a notificações de alteração de propriedade, a associação não será atualizada no arquivo de configurações quando a propriedade for alterada.

Alguns componentes do Windows Forms, como ToolStripItem, não dão suporte a associações de configurações.

Serialização de configurações

Quando LocalFileSettingsProvider deve salvar configurações em disco, ele executa as seguintes ações:

  1. Usa a reflexão para examinar todas as propriedades definidas em sua classe derivada ApplicationSettingsBase, encontrando aquelas que são aplicadas com ApplicationScopedSettingAttribute ou UserScopedSettingAttribute.

  2. Serializa a propriedade em disco. Ele primeiro tenta chamar o ConvertToString ou ConvertFromString no TypeConverterassociado ao tipo. Se isso não for bem-sucedido, ele usará a serialização XML.

  3. Determina quais configurações vão em quais arquivos, com base no atributo da configuração.

Se você implementar sua própria classe de configurações, poderá usar a SettingsSerializeAsAttribute para marcar uma configuração para serialização binária ou personalizada usando a enumeração SettingsSerializeAs. Para obter mais informações sobre como criar sua própria classe de configurações no código, consulte How to: Create Application Settings.

Locais de arquivo de configurações

O local dos arquivos de usuário app.exe.config e .config diferirá com base no modo como o aplicativo é instalado. Para um aplicativo baseado em Windows Forms copiado para o computador local, app.exe.config residirão no mesmo diretório do diretório base do arquivo executável principal do aplicativo e usuário.config residirão no local especificado pela propriedade Application.LocalUserAppDataPath. Para um aplicativo instalado por meio do ClickOnce, ambos os arquivos residirão no Diretório de Dados clickOnce abaixo de %InstallRoot%\Documents and Settings\nome de usuário\Configurações Locais.

O local de armazenamento desses arquivos será ligeiramente diferente se um usuário tiver habilitado perfis de roaming, o que permite que um usuário defina configurações diferentes do Windows e do aplicativo quando estiver usando outros computadores em um domínio. Nesse caso, os aplicativos ClickOnce e aplicativos não ClickOnce terão seus arquivos de app.exe.config e usuário.config armazenados em %InstallRoot%\Documentos e Configurações\nome de usuário\Dados do Aplicativo.

Para obter mais informações sobre como o recurso Configurações do Aplicativo funciona com a nova tecnologia de implantação, consulte ClickOnce e Configurações de Aplicativo. Para obter mais informações sobre o Diretório de Dados clickOnce, consulte acessando dados locais e remotos em aplicativos ClickOnce.

Configurações e segurança do aplicativo

As configurações de aplicativo são projetadas para funcionar em confiança parcial, um ambiente restrito que é o padrão para aplicativos do Windows Forms hospedados pela Internet ou por uma intranet. Nenhuma permissão especial além da confiança parcial é necessária para usar as configurações do aplicativo com o provedor de configurações padrão.

Quando as configurações do aplicativo são usadas em um aplicativo ClickOnce, o arquivo user.config é armazenado no diretório de dados ClickOnce. O tamanho do arquivo user.config do aplicativo não pode exceder a cota do diretório de dados definida pelo ClickOnce. Para obter mais informações, consulte ClickOnce e Configurações do Aplicativo.

Provedores de configurações personalizadas

Na arquitetura de Configurações de Aplicativo, há um acoplamento flexível entre a classe wrapper de configurações de aplicativos, derivada de ApplicationSettingsBasee o provedor ou provedores de configurações associados, derivado de SettingsProvider. Essa associação é definida apenas pelo SettingsProviderAttribute aplicado à classe wrapper ou às suas propriedades individuais. Se um provedor de configurações não for especificado explicitamente, o provedor padrão, LocalFileSettingsProvider, será usado. Como resultado, essa arquitetura dá suporte à criação e ao uso de provedores de configurações personalizadas.

Por exemplo, suponha que você queira desenvolver e usar SqlSettingsProvider, um provedor que armazenará todos os dados de configurações em um banco de dados do Microsoft SQL Server. Sua classe derivada de SettingsProviderreceberia essas informações em seu método Initialize como um parâmetro do tipo System.Collections.Specialized.NameValueCollection. Em seguida, você implementaria o método GetPropertyValues para recuperar suas configurações do armazenamento de dados e SetPropertyValues para salvá-las. Seu provedor pode usar o SettingsPropertyCollection fornecido para GetPropertyValues para determinar o nome, o tipo e o escopo da propriedade, bem como quaisquer outros atributos de configurações definidos para essa propriedade.

Seu provedor precisará implementar uma propriedade e um método cujas implementações podem não ser óbvias. A propriedade ApplicationName é uma propriedade abstrata de SettingsProvider; você deve programá-lo para retornar o seguinte:

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

Sua classe derivada também deve implementar um método Initialize que não aceita argumentos e não retorna nenhum valor. Esse método não é definido por SettingsProvider.

Por fim, você implementa IApplicationSettingsProvider em seu provedor para fornecer suporte para atualizar as configurações, reverter as configurações para seus padrões e atualizar as configurações de uma versão de aplicativo para outra.

Depois de implementar e compilar seu provedor, você precisará instruir sua classe de configurações a usar esse provedor em vez do padrão. Você faz isso por meio do SettingsProviderAttribute. Se aplicado a uma classe de configurações inteira, o provedor será usado para cada configuração definida pela classe; se aplicado a configurações individuais, a arquitetura de Configurações de Aplicativo usa esse provedor somente para essas configurações e usa LocalFileSettingsProvider para o restante. O exemplo de código a seguir mostra como instruir a classe de configurações a usar seu provedor 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

Um provedor pode ser chamado de vários threads simultaneamente, mas ele sempre gravará no mesmo local de armazenamento; portanto, a arquitetura de Configurações de Aplicativos só criará uma única instância da sua classe de provedor.

Importante

Você deve garantir que seu provedor seja thread-safe e só permita que um thread de cada vez escreva nos arquivos de configuração.

Seu provedor não precisa dar suporte a todos os atributos de configurações definidos no namespace System.Configuration, embora ele precise de um suporte mínimo ApplicationScopedSettingAttribute e UserScopedSettingAttributee também deve dar suporte a DefaultSettingValueAttribute. Para esses atributos que ele não dá suporte, seu provedor deve simplesmente falhar sem notificação; não deve gerar uma exceção. No entanto, se a classe de configurações usar uma combinação inválida de atributos, como aplicar ApplicationScopedSettingAttribute e UserScopedSettingAttribute à mesma configuração, o provedor deverá lançar uma exceção e interromper a operação.

Consulte também