Partilhar via


Arquitetura de configurações do aplicativo

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

A arquitetura de configurações do aplicativo suporta a definição de configurações fortemente tipadas com o escopo do aplicativo ou do usuário e a persistência das 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.

São fornecidas interfaces que permitem que componentes personalizados persistam suas próprias configurações quando são hospedados em um aplicativo. Usando teclas de configurações, 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 que são 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 do 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 definições específicas do utilizador

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

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

  • Validação de configurações, antes de serem alteradas ou antes de serem salvas

As configurações podem ser descritas usando vários atributos definidos dentro do namespace System.Configuration; eles são descritos em Application Settings Attributes. 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 própria classe ApplicationSettingsBase não persiste ou carrega configurações; Esse trabalho cabe ao 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 oferece suporte ao fornecimento de dados estáticos de configuração do aplicativo por meio do arquivo machine.config do computador local ou dentro de um arquivo app.exe.config que você implanta com seu aplicativo. A classe LocalFileSettingsProvider expande esse suporte nativo das seguintes maneiras:

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

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

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

Todos os três arquivos de configuração armazenam configurações em formato XML. O elemento XML de nível superior para configurações de escopo de aplicativo é <appSettings>, enquanto <userSettings> é usado para configurações de escopo do usuário. Um arquivo app.exe.config que contém configurações de escopo de aplicativo e padrões para configurações de 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 dentro da seção de configurações do aplicativo de um arquivo de configuração, consulte Application Settings Schema.

Ligações de configurações

As configurações do aplicativo usam a arquitetura de vinculaçã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 vincular uma configuração de aplicativo a um componente que ofereça suporte à interface IBindableComponent. Além disso, o componente deve implementar um evento de alteração para uma propriedade acoplada específica, ou notificar as definições da aplicação de que a propriedade foi alterada por meio da interface INotifyPropertyChanged. Se o componente não implementar IBindableComponent e você estiver vinculando 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 oferecem suporte a associações de configurações.

Serialização de configurações

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

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

  2. Serializa a propriedade para o disco. Primeiro, tenta chamar o ConvertToString ou ConvertFromString do TypeConverterassociado ao tipo. Se isso não for bem-sucedido, ele usará a serialização XML em vez disso.

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

Se implementar a sua própria classe de configurações, pode usar o SettingsSerializeAsAttribute para assinalar 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 Como criar configurações do aplicativo.

Locais dos arquivos de configurações

A localização dos arquivos de utilizador.config .exe.config e será diferente, dependendo de como o aplicativo foi instalado. Para um aplicativo baseado em Windows Forms copiado para o computador local, app.exe.config residirá no mesmo diretório que o diretório base do arquivo executável principal do aplicativo e usuário.config residirá no local especificado pela propriedade Application.LocalUserAppDataPath. Para um aplicativo instalado por meio de ClickOnce, ambos os arquivos residirão no diretório de dados ClickOnce abaixo de %InstallRoot%\Documents and Settings\nome de usuário\Local Settings.

O local de armazenamento desses arquivos é ligeiramente diferente se um usuário tiver habilitado perfis móveis, o que permite que um usuário defina diferentes configurações do Windows e do aplicativo quando estiver usando outros computadores dentro de um domínio. Nesse caso, tanto as aplicações ClickOnce como as que não são ClickOnce terão os seus ficheiros de utilizador app.exe.config e .config armazenados em "%InstallRoot%\Documents and Settings\nome de utilizador\Application Data".

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 do 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 do aplicativo são projetadas para funcionar em confiança parcial, um ambiente restrito que é o padrão para aplicativos Windows Forms hospedados pela Internet ou por uma intranet. Não são necessárias permissões especiais além da confiança parcial 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 de diretório de dados definida por ClickOnce. Para obter mais informações, consulte ClickOnce e Configurações do aplicativo.

Provedores de configurações personalizadas

Na arquitetura de Definições da Aplicação, há um acoplamento frouxo entre a classe wrapper de definições de aplicações, derivada de ApplicationSettingsBase, e o fornecedor ou fornecedores de definições associados, derivados de SettingsProvider. Essa associação é definida apenas pelo SettingsProviderAttribute aplicado à classe wrapper ou 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 oferece 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 do 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 salvá-las. Seu provedor pode usar os SettingsPropertyCollection fornecidos ao GetPropertyValues para determinar o nome, o tipo e o escopo da propriedade, bem como quaisquer outros atributos de configuração 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 usa argumentos e não retorna nenhum valor. Este método não é definido por SettingsProvider.

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

Depois de implementar e compilar seu provedor, você precisa instruir sua classe de configurações para usar esse provedor em vez do padrão. Você consegue isso através do SettingsProviderAttribute. Se aplicado a uma classe de configurações inteira, o provedor é usado para cada configuração que a classe define; se aplicada a configurações individuais, a arquitetura de Configurações do Aplicativo usa esse provedor apenas para essas configurações e usa LocalFileSettingsProvider para o resto. O exemplo de código a seguir mostra como instruir a classe settings para 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 sempre gravará no mesmo local de armazenamento; portanto, a arquitetura de Configurações do Aplicativo só instanciará uma única instância da sua classe de provedor.

Importante

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

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

Ver também