Architektur der Anwendungseinstellungen

In diesem Thema wird beschrieben, wie die Architektur der Anwendungseinstellungen funktioniert. Außerdem werden erweiterte Funktionen der Architektur erläutert, z.B. gruppierte Einstellungen und Einstellungsschlüssel.

Die Architektur der Anwendungseinstellungen unterstützt definierende, stark typisierte Einstellungen mit Geltungsbereich Anwendung oder Benutzer sowie die Beibehaltung der Einstellungen zwischen Anwendungssitzungen. Die Architektur bietet eine Standardpersistenz-Engine zum Speichern von Einstellungen und Laden aus dem lokalen Dateisystem. Die Architektur definiert auch Schnittstellen zur Bereitstellung einer benutzerdefinierten Persistenz-Engine.

Schnittstellen werden bereitgestellt, die benutzerdefinierten Komponenten ermöglichen, ihre eigenen Einstellungen beizubehalten, wenn sie in einer Anwendung gehostet werden können. Mithilfe von Einstellungsschlüsseln können Komponenten Einstellungen für mehrere Instanzen der Komponente getrennt halten.

Definieren von Einstellungen

Die Architektur der Anwendungseinstellungen wird in ASP.NET und in Windows Forms verwendet und enthält eine Reihe von Basisklassen, die beide Umgebungen gemeinsam verwenden. Am wichtigsten ist die SettingsBase, die den Zugriff auf Einstellungen über eine Auflistung bietet und Methoden auf niedriger Stufe zum Laden und Speichern von Einstellungen bereitstellt. Jede Umgebung implementiert eine eigene, von SettingsBase abgeleitete Klasse, um zusätzliche Einstellungsfunktionen für diese Umgebung bereitzustellen. In einer Windows Forms-basierten Anwendung müssen alle Anwendungseinstellungen in einer Klasse definiert werden, die von der ApplicationSettingsBase-Klasse abgeleitet ist. Dadurch wird der Basisklasse die folgende Funktionalität hinzugefügt:

  • Lade- und Speichervorgänge auf höherer Ebene

  • Unterstützung für benutzerspezifische Einstellungen

  • Wiederherstellen der vordefinierten Standardeinstellungen eines Benutzers

  • Aktualisieren von Einstellungen aus einer früheren Anwendungsversion

  • Überprüfen von Einstellungen, bevor sie geändert oder bevor sie gespeichert werden

Die Einstellungen können mithilfe einer Reihe von im System.Configuration-Namespace definierten Attributen beschrieben werden. Diese werden unter Attribute für Anwendungseinstellungen beschrieben. Wenn Sie eine Einstellung definieren, müssen Sie sie mit ApplicationScopedSettingAttribute oder UserScopedSettingAttribute anwenden. Damit wird beschrieben, ob die Einstellung für die gesamte Anwendung oder nur für den aktuellen Benutzer gilt.

Das folgende Codebeispiel definiert eine benutzerdefinierte Einstellungsklasse mit einer Einstellung: 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

Beibehaltung von Einstellungen

Die ApplicationSettingsBase-Klasse lädt oder speichert nicht selbst Einstellungen. Diese Aufgabe übernimmt der Einstellungsanbieter, eine Klasse, die von SettingsProvider abgeleitet wird. Wenn eine abgeleitete Klasse von ApplicationSettingsBase keinen Einstellungsanbieter über das SettingsProviderAttribute angibt, wird der Standardanbieter LocalFileSettingsProvider verwendet.

Das Konfigurationssystem, das ursprünglich mit .NET Framework veröffentlicht wurde, unterstützt die Bereitstellung von statischen Anwendungskonfigurationsdaten über die Datei „machine.config“ des lokalen Computers oder in einer Datei „app.exe.config“, die Sie mit Ihrer Anwendung bereitstellen. Die LocalFileSettingsProvider-Klasse erweitert diese native Unterstützung auf folgende Weise:

  • Anwendungsspezifische Einstellungen können in der Datei machine.config oder app.exe.config gespeichert werden. Die Datei machine.config ist immer schreibgeschützt, während app. exe.config aufgrund von Sicherheitsüberlegungen für die meisten Anwendungen schreibgeschützt ist.

  • Benutzerspezifische Einstellungen können in app. exe.config-Dateien gespeichert werden und werden dann als statische Standardwerte behandelt.

  • Nicht standardmäßige Benutzerbereichseinstellungen werden in einer neuen Datei gespeichert, user.config. Sie können mit DefaultSettingValueAttribute einen Standardwert für eine benutzerspezifische Einstellung angeben. Da sich benutzerspezifische Einstellungen häufig während der Ausführung der Anwendung ändern, hat user.config immer Lese-/Schreibzugriff. Weitere Informationen finden Sie unter Wo sind Einstellungen mit Benutzerbereich gespeichert.

Alle drei Konfigurationsdateien speichern Einstellungen im XML-Format. Das XML-Element der obersten Ebene für anwendungsspezifische Einstellungen ist <appSettings>, während <userSettings> für die benutzerspezifischen Einstellungen verwendet wird. Eine app. exe.config-Datei mit anwendungsspezifischen Einstellungen und Standardwerten für benutzerspezifische Einstellungen sieht wie folgt aus:

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

Eine Definition der Elemente im Abschnitt Anwendungseinstellungen einer Konfigurationsdatei finden Sie unter Schema für Anwendungseinstellungen.

Einstellungen für Bindungen

Anwendungseinstellungen verwenden die Datenbindungsarchitektur von Windows Forms, um die bidirektionale Kommunikation von Einstellungsaktualisierungen zwischen dem Einstellungsobjekt und den Komponenten bereitzustellen. Wenn Sie mit Visual Studio Anwendungseinstellungen erstellen und diese Komponenteneigenschaften zuordnen, werden die Bindungen automatisch generiert.

Sie können nur eine Anwendungseinstellung an eine Komponente binden, die die IBindableComponent-Schnittstelle unterstützt. Darüber hinaus muss die Komponente ein Änderungsereignis für eine bestimmte gebundene Eigenschaft implementieren oder Anwendungseinstellungen über die INotifyPropertyChanged-Schnittstelle darüber informieren, dass sich die Eigenschaft geändert hat. Wenn die Komponente keine IBindableComponent implementiert und Sie über Visual Studio binden, werden die gebundenen Eigenschaften beim ersten Mal festgelegt, aber nicht aktualisiert. Wenn die Komponente IBindableComponent implementiert, aber keine Benachrichtigungen über Eigenschaftsänderungen unterstützt, wird die Bindung nicht in der Einstellungsdatei aktualisiert, wenn sich die Eigenschaft ändert.

Einige Windows Forms-Komponenten, wie z. B. ToolStripItem, unterstützen das Binden von Einstellungen nicht.

Serialisierung von Einstellungen

Wenn der LocalFileSettingsProvider Einstellungen auf einem Datenträger speichern muss, führt er folgende Aktionen aus:

  1. Verwenden von Reflektion, um alle für die abgeleitete ApplicationSettingsBase-Klasse definierten Einstellungen zu suchen, wobei diejenigen gefunden werden, die mit dem ApplicationScopedSettingAttribute oder dem UserScopedSettingAttribute angewandt werden.

  2. Serialisieren der Eigenschaft auf den Datenträger. Zunächst wird versucht, die ConvertToString oder ConvertFromString in dem TypeConverter aufzurufen, der dem Typ zugeordnet ist. Schlägt der Versuch fehl, wird stattdessen die XML-Serialisierung angewendet.

  3. Bestimmen, welche Einstellungen in welche Datei übergehen, basierend auf dem Attribut der Einstellung.

Wenn Sie eine eigene Einstellungsklasse implementieren, können Sie mit SettingsSerializeAsAttribute und der SettingsSerializeAs-Enumeration eine Einstellung für die binäre oder benutzerdefinierte Serialisierung markieren. Weitere Informationen zum Erstellen eigener Einstellungen finden Sie unter Vorgehensweise: Erstellen von Anwendungseinstellungen.

Speicherorte für Einstellungsdateien

Der Speicherort der Dateien app. exe.config und benutzer.config hängt davon ab, wie die Anwendung installiert ist. Bei einer Windows Forms-basierten Anwendung, die auf den lokalen Computer kopiert wurde, befindet sich die Datei „app.exe.config“ im gleichen Verzeichnis wie das Basisverzeichnis der Hauptausführungsdatei der Anwendung, und „Benutzer.config“ wird an dem von der Application.LocalUserAppDataPath-Eigenschaft angegebenen Speicherort gespeichert. Bei einer mit ClickOnce installierten Anwendung befinden sich die beiden Dateien im ClickOnce-Datenverzeichnis unter „%InstallRoot%\Dokumente“ und „Einstellungen\Benutzername\Lokale Einstellungen“.

Der Speicherort dieser Dateien unterscheidet sich geringfügig, wenn die Benutzer*innen Roamingprofile aktiviert haben. Die Benutzer*innen können dann verschiedene Windows- oder Anwendungseinstellungen definieren, wenn sie andere Computer in einer Domäne verwenden. In diesem Fall werden die Dateien „app.exe.config“ und „Benutzer.config“ von ClickOnce-Anwendungen und Nicht-ClickOnce-Anwendungen unter „%InstallRoot%\Dokumente“ und „Einstellungen\Benutzername\Anwendungsdaten“ gespeichert.

Weitere Informationen zur Funktionsweise der Anwendungseinstellungen mit der neuen Bereitstellungstechnologie finden Sie unter ClickOnce und Anwendungseinstellungen. Weitere Informationen zum ClickOnce-Datenverzeichnis finden Sie unter Zugreifen auf lokale und Remotedaten in ClickOnce-Anwendungen.

Einstellungen und Sicherheit von Anwendungen

Anwendungseinstellungen sollen in teilweiser Vertrauenswürdigkeit, einer eingeschränkten Umgebung, funktionieren, die der Standard für über das Internet oder ein Intranet gehostete Windows Forms-Anwendungen ist. Außer teilweiser Vertrauenswürdigkeit sind keine besonderen Berechtigungen erforderlich, um Anwendungseinstellungen mit dem Standardeinstellungsanbieter zu verwenden.

Wenn Anwendungseinstellungen in einer ClickOnce-Anwendung verwendet werden, wird die Datei „user.config“ im ClickOnce-Datenverzeichnis gespeichert. Die Größe der Datei „user.config“ der Anwendung kann das Datenverzeichniskontingent nicht überschreiten, das von ClickOnce festgelegt wurde. Weitere Informationen finden Sie unter ClickOnce und Anwendungseinstellungen.

Benutzerdefinierte Einstellungsanbieter

In der Architektur der Anwendungseinstellungen besteht eine lose Kopplung zwischen der Wrapperklasse für Anwendungseinstellungen, die von ApplicationSettingsBase abgeleitet ist, und den zugeordneten Einstellungsanbietern, die von SettingsProvider abgeleitet werden. Diese Zuordnung wird nur vom SettingsProviderAttribute definiert, das auf die Wrapperklasse oder ihre individuellen Eigenschaften angewandt wurde. Wenn ein Einstellungsanbieter nicht explizit angegeben ist, wird der Standardanbieter LocalFileSettingsProvider verwendet. Daher unterstützt diese Architektur das Erstellen und Verwenden von benutzerdefinierten Einstellungsanbietern.

Nehmen wir beispielsweise an, dass Sie SqlSettingsProvider, entwickeln und verwenden möchten, einen Anbieter, der sämtliche Einstellungsdaten in einer Microsoft SQL Server-Datenbank speichert. Die abgeleitete SettingsProvider-Klasse empfängt dann diese Informationen in ihrer Initialize-Methode als Parameter vom Typ System.Collections.Specialized.NameValueCollection. Implementieren Sie anschließend die GetPropertyValues-Methode, um die Einstellungen aus dem Datenspeicher abzurufen, und SetPropertyValues, um sie zu speichern. Der Anbieter kann die SettingsPropertyCollection, die für GetPropertyValues bereitgestellt wurde, verwenden, um den Namen, Typ und Geltungsbereich der Eigenschaft und andere Einstellungsattribute zu bestimmen, die für diese Eigenschaft definiert wurden.

Der Anbieter muss eine Eigenschaft und eine Methode implementieren, deren Implementierungen möglicherweise nicht offensichtlich sind. Die ApplicationName-Eigenschaft ist eine abstrakte Eigenschaft von SettingsProvider. Sie sollten sie so programmieren, dass sie Folgendes zurückgibt:

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

Die abgeleitete Klasse muss außerdem eine Initialize-Methode implementieren, die keine Argumente akzeptiert und keinen Wert zurückgibt. Diese Methode wird nicht durch SettingsProvider definiert.

Implementieren Sie abschließend IApplicationSettingsProvider für den Anbieter, um Unterstützung für die Aktualisierung von Einstellungen, das Zurücksetzen von Einstellungen auf ihre Standardwerte und das Aktualisieren von Einstellungen von einer Anwendungsversion auf eine andere bereitzustellen.

Nachdem Sie Ihren Anbieter implementiert und kompiliert haben, müssen Sie Ihre Einstellungenklasse anweisen, diesen Anbieter anstelle des standardmäßigen Anbieters zu verwenden. Sie erreichen dies über das SettingsProviderAttribute. Bei Anwendung auf eine vollständige Einstellungsklasse wird der Anbieter für jede Einstellung verwendet, die die Klasse definiert. Bei Anwendung auf einzelne Einstellungen verwendet die Architektur für Anwendungseinstellungen den Anbieter nur für diese Einstellungen und für die übrigen den LocalFileSettingsProvider. Das folgende Codebeispiel veranschaulicht, wie die Einstellungenklasse angewiesen wird, den benutzerdefinierten Anbieter zu verwenden.

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

Ein Anbieter kann von mehreren Threads gleichzeitig aufgerufen werden, schreibt jedoch immer in den gleichen Speicherort. Aus diesem Grund instanziiert die Architektur für Anwendungseinstellungen immer nur eine einzelne Instanz der Anbieterklasse.

Wichtig

Sie sollten sicherstellen, dass der Anbieter threadsicher ist und jeweils nur einem Thread gestattet, in die Konfigurationsdateien zu schreiben.

Der Anbieter muss nicht alle im System.Configuration-Namespace definierten Einstellungsattribute unterstützen, obwohl er mindestens das ApplicationScopedSettingAttribute und das UserScopedSettingAttribute unterstützen muss und das DefaultSettingValueAttribute unterstützen sollte. Für die Attribute, die nicht unterstützt werden, sollte der Anbieter ohne Benachrichtigung fehlschlagen und keine Ausnahme auslösen. Wenn die Einstellungsklasse jedoch eine ungültige Kombination von Attributen verwendet, z. B. durch Anwenden von ApplicationScopedSettingAttribute und UserScopedSettingAttribute auf die gleiche Einstellung, sollte der Anbieter eine Ausnahme auslösen und den Vorgang beenden.

Weitere Informationen