Condividi tramite


Architettura Impostazioni applicazione

Aggiornamento: novembre 2007

In questo argomento viene descritto il funzionamento dell'architettura Impostazioni applicazione e ne vengono analizzate alcune funzioni avanzate, quali i raggruppamenti di impostazioni e le chiavi delle impostazioni.

L'architettura Impostazioni applicazione supporta la definizione di impostazioni fortemente tipizzate con ambito di applicazione o utente, nonché la persistenza delle impostazioni tra le varie sessioni dell'applicazione. Fornisce un motore di persistenza predefinito per il salvataggio e il caricamento delle impostazioni nel/dal file system locale. L'architettura definisce inoltre interfacce che consentono di fornire un motore di persistenza personalizzato.

Vengono fornite interfacce che consentono a componenti personalizzati di rendere persistenti le rispettive impostazioni quando vengono utilizzati in un'applicazione. Mediante le chiavi delle impostazioni, i componenti possono tenere separate le impostazioni di più istanze del componente.

Definizione delle impostazioni

L'architettura Impostazioni applicazione viene utilizzata sia in ASP.NET che in Windows Form e contiene diverse classi base condivise in entrambi gli ambienti. La classe più importante è SettingsBase, che consente l'accesso alle impostazioni mediante un insieme e fornisce metodi di basso livello per il caricamento e il salvataggio delle impostazioni. In ogni ambiente viene implementata una classe specifica derivata dalla classe base SettingsBase per arricchire l'ambiente stesso di ulteriori funzionalità delle impostazioni. In un'applicazione basata su Windows Form tutte le impostazioni dell'applicazione devono essere definite su una classe derivata dalla classe ApplicationSettingsBase e ciò aggiunge le funzionalità seguenti alla classe base:

  • Operazioni di caricamento e salvataggio di alto livello

  • Supporto per impostazioni con ambito di utente

  • Ripristino dei valori predefiniti delle impostazioni dell'utente

  • Aggiornamento delle impostazioni da una versione precedente dell'applicazione

  • Convalida delle impostazioni, prima della modifica o prima del salvataggio

È possibile descrivere le impostazioni utilizzando alcuni attributi definiti nello spazio dei nomi System.Configuration. Per ulteriori informazioni, vedere Attributi delle impostazioni delle applicazioni. Quando si definisce un'impostazione, è necessario applicarla con la classe ApplicationScopedSettingAttribute oppure con la classe UserScopedSettingAttribute, che descrive se l'impostazione si applica all'intera applicazione o solo all'utente corrente.

Nell'esempio di codice riportato di seguito viene definita una classe di impostazioni personalizzata con una sola impostazione, BackgroundColor.

Imports System.Configuration

Public Class MyAppSettings
    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
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;
        }
    }
}

Persistenza delle impostazioni

La classe ApplicationSettingsBase non esegue la persistenza o il caricamento delle impostazioni. Tale operazione è effettuata dal provider di impostazioni, una classe che deriva da SettingsProvider. Se una classe derivata dalla classe ApplicationSettingsBase non specifica un provider di impostazioni mediante la classe SettingsProviderAttribute, viene utilizzato il provider predefinito LocalFileSettingsProvider.

Il sistema di configurazione reso disponibile in origine con .NET Framework supporta la fornitura di dati di configurazione dell'applicazione statici mediante il file machine.config del computer locale o in un file app.exe.config da distribuire con l'applicazione. La classe LocalFileSettingsProvider espande tale supporto nativo nei modi seguenti:

  • È possibile archiviare le impostazioni con ambito di applicazione nel file machine.config o app.exe.config. Il file machine.config è sempre di sola lettura mentre app.exe.config è di sola lettura per gran parte delle applicazioni per motivi di sicurezza.

  • Le impostazioni possono essere archiviate con ambito di utente in file app.exe.config e in tal caso sono considerate come valori predefiniti statici.

  • Le impostazioni con ambito di utente non predefinite sono archiviate in un nuovo file, utente.config, dove utente è il nome dell'utente che esegue l'applicazione al momento. È possibile specificare un valore predefinito per un'impostazione con ambito di utente con DefaultSettingValueAttribute. Poiché le impostazioni con ambito di utente subiscono spesso modifiche durante l'esecuzione dell'applicazione, il file user.config è sempre accessibile in lettura e scrittura.

In tutti e tre i file di configurazione le impostazioni sono archiviate in formato XML. L'elemento XML superiore per le impostazioni con ambito di applicazione è <appSettings>, mentre <userSettings> è utilizzato per impostazioni con ambito di utente. Un file app.exe.config contenente impostazioni con ambito sia di applicazione sia di utente si presenta come segue:

<?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>

Per la definizione degli elementi all'interno della sezione relativa a Impostazioni applicazione di un file di configurazione, vedere Schema Application Settings.

Associazione delle impostazioni

L'architettura Impostazioni applicazione utilizza l'architettura di associazione dati di Windows Form per consentire la comunicazione bidirezionale degli aggiornamenti delle impostazioni tra i relativi componenti e oggetti. Se si utilizza Visual Studio per creare le impostazioni delle applicazioni e assegnarle alle proprietà dei componenti, queste associazioni verranno generate automaticamente.

Un'impostazione dell'applicazione può essere associata soltanto a un componente che supporta l'interfaccia IBindableComponent. Il componente, inoltre, deve implementare un evento di modifica per una specifica proprietà associata oppure deve notificare alla funzione Impostazioni applicazione che la proprietà è stata modificata tramite l'interfaccia INotifyPropertyChanged. Se il componente non implementa IBindableComponent e l'associazione viene eseguita tramite Visual Studio, le proprietà associate verranno inizialmente impostate ma non verranno aggiornate. Se il componente implementa IBindableComponent ma non supporta le notifiche per la modifica delle proprietà, l'associazione non verrà aggiornata nel file delle impostazioni quando la proprietà viene modificata.

Alcuni componenti Windows Form, ad esempio ToolStripItem, non supportano le associazioni delle impostazioni.

Serializzazione delle impostazioni

Quando LocalFileSettingsProvider deve salvare le impostazioni su disco, esegue le azioni seguenti:

  1. Utilizza la reflection per esaminare tutte le proprietà definite sulla classe derivata da ApplicationSettingsBase, trovando quelle applicate con la classe ApplicationScopedSettingAttribute o UserScopedSettingAttribute.

  2. Serializza la proprietà su disco. Tenta in primo luogo di chiamare il metodo ConvertToString o ConvertFromString sulla classe associata TypeConverter del tipo. Se il tentativo non riesce, utilizza la serializzazione XML.

  3. Stabilisce un'associazione tra impostazioni e file di destinazione, in base all'attributo dell'impostazione.

Se si implementa una propria classe di impostazioni, è possibile utilizzare SettingsSerializeAsAttribute per contrassegnare un'impostazione per la serializzazione binaria o personalizzata mediante l'enumerazione SettingsSerializeAs. Per ulteriori informazioni sulla creazione di una propria classe di impostazioni nel codice, vedere Procedura: creare le impostazioni dell'applicazione.

Posizioni dei file delle impostazioni

La posizione dei file app.exe.config e utente.config dipende dalla modalità di installazione dell'applicazione. Per un'applicazione basata su Windows Form copiata nel computer locale, il file app.exe.config si troverà nella stessa directory della directory di base del file eseguibile principale dell'applicazione, mentre utente.config risiederà nel percorso specificato dalla proprietà Application.LocalUserAppDataPath. Per un'applicazione installata tramite ClickOnce, entrambi i file risiederanno nella directory Dati ClickOnce nel percorso %InstallRoot%\\Documents and Settings\\nomeutente\Impostazioni locali.

La posizione di archiviazione dei file è leggermente diversa se l'utente ha attivato i profili comuni in quanto ciò gli consente di definire impostazioni di Windows e di applicazione diverse quando utilizza altri computer all'interno di un dominio. In tal caso tanto per le applicazioni ClickOnce quanto per quelle non ClickOnce i file app.exe.config e utente.config verranno archiviati in %InstallRoot%\\Documents and Settings\nomeutente\Dati applicazioni.

Per ulteriori informazioni sul funzionamento di Impostazioni applicazione con la nuova tecnologia di distribuzione, vedere Impostazioni dell'applicazione e ClickOnce. Per ulteriori informazioni sulla directory Dati ClickOnce, vedere Accesso a dati locali e remoti in applicazioni ClickOnce.

Sicurezza di Impostazioni applicazione

La funzione Impostazioni applicazione è stata progettata per il funzionamento in contesti di attendibilità parziale, ovvero in un ambiente limitato che costituisce l'impostazione predefinita per le applicazioni Windows Form accessibili in Internet o in una rete intranet. Per utilizzare Impostazioni applicazione con il provider di impostazioni predefinito non sono necessarie autorizzazioni speciali oltre all'attendibilità parziale.

Quando la funzione Impostazioni applicazione viene utilizzata in un'applicazione ClickOnce, il file user.config viene archiviato nella directory dei dati di ClickOnce. La dimensione del file user.config dell'applicazione non può superare la quota della directory dei dati impostata da ClickOnce. Per ulteriori informazioni, vedere Impostazioni dell'applicazione e ClickOnce.

Provider di impostazioni personalizzati

Nell'architettura Impostazioni applicazione esiste una debole associazione tra la classe wrapper di Impostazioni applicazione, derivata dalla classe ApplicationSettingsBase, e i provider di impostazioni associati, derivati dalla classe SettingsProvider. Tale associazione è definita solo dalla classe SettingsProviderAttribute applicata alla classe wrapper o alle singole proprietà di questa. Se non viene specificato espressamente un provider di impostazioni, viene utilizzato il provider predefinito LocalFileSettingsProvider. Di conseguenza, l'architettura supporta la creazione e l'utilizzo di provider di impostazioni personalizzati.

Si supponga, ad esempio, di desiderare di sviluppare e utilizzare SqlSettingsProvider, un provider che archivi tutti i dati delle impostazioni in un database di Microsoft SQL Server. La classe derivata da SettingsProvider riceverebbe tali informazioni nel metodo Initialize come parametro del tipo System.Collections.Specialized.NameValueCollection. Si passerebbe quindi a implementare il metodo GetPropertyValues per recuperare le impostazioni dall'archivio di dati e SetPropertyValues per salvarle. Il provider è in grado di utilizzare la classe SettingsPropertyCollection fornita a GetPropertyValues per determinare nome, tipo e ambito della proprietà, nonché eventuali altri attributi di impostazioni definiti per essa.

Sarà necessario per il provider eseguire un'implementazione non ovvia di una proprietà e un metodo. ApplicationName è una proprietà astratta della classe SettingsProvider. Programmarla affinché restituisca quanto segue:

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
public override string ApplicationName
{
    get
    {
        return (System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
    }
    set
    {
        // Do nothing.
    }
}

La classe derivata, inoltre, deve implementare un metodo Initialize che non utilizzi argomenti e non restituisca valori. Questo metodo non è definito dalla classe SettingsProvider.

Si implementa infine IApplicationSettingsProvider nel provider per consentire l'aggiornamento delle impostazioni, il ripristino dei valori predefiniti e l'aggiornamento delle applicazioni da una versione all'altra di un'applicazione.

Terminata l'implementazione e la compilazione del provider, è necessario configurare la classe delle impostazioni in modo che utilizzi tale provider anziché quello predefinito. Eseguire tale operazione mediante la classe SettingsProviderAttribute. Se applicato a un'intera classe di impostazioni, il provider viene utilizzato per ogni impostazione definita nella classe. Se applicato a singole impostazioni, l'architettura Impostazioni applicazione utilizza il provider per le impostazioni specificate e la classe LocalFileSettingsProvider per le altre. Nell'esempio di codice riportato di seguito viene illustrato come configurare la classe delle impostazioni per l'utilizzo del provider personalizzato.

Imports System.Configuration

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

    ' Implementation goes here.
End Class
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace ApplicationSettingsArchitectureCS
{
    class CustomSettings : ApplicationSettingsBase
    {
        // Implementation goes here.
    }
}

Un provider può essere chiamato da più thread contemporaneamente ma scriverà sempre nella stessa posizione di archiviazione. Di conseguenza, l'architettura Impostazioni applicazione creerà sempre una sola istanza della classe del provider.

Nota importante:

È necessario accertarsi che il provider sia thread-safe e che consenta a un solo thread alla volta di scrivere nei file di configurazione.

Non è necessario che il provider supporti tutti gli attributi delle impostazioni definiti nello spazio dei nomi System.Configuration ma deve almeno supportare le classi ApplicationScopedSettingAttribute e UserScopedSettingAttribute nonché DefaultSettingValueAttribute. Per gli attributi non supportati, è sufficiente che il provider generi l'errore senza visualizzare avvisi. Non deve produrre un'eccezione. Se la classe delle impostazioni utilizza una combinazione non valida di attributi, tuttavia, ad esempio applicando ApplicationScopedSettingAttribute e UserScopedSettingAttribute alla stessa impostazione, il provider deve generare un'eccezione e annullare l'operazione.

Vedere anche

Concetti

Cenni preliminari sulle impostazioni delle applicazioni

Impostazioni delle applicazioni per i controlli personalizzati

Impostazioni dell'applicazione e ClickOnce

Riferimenti

Schema Application Settings

ApplicationSettingsBase

SettingsProvider

LocalFileSettingsProvider