語言

應用程式設定架構

本主題描述應用程式設定的運作方式,並且瀏覽架構的進階功能 (例如群組設定和設定索引鍵)。

應用程式設定架構支援在應用程式範圍或使用者範圍內定義強類型設定,並在應用程式工作階段之間持久化這些設定。 此架構提供預設持續性引擎,可將設定儲存至本機檔案系統和從中載入設定。 此架構也定義介面來提供自訂持續性引擎。

提供的介面可讓自訂元件裝載於應用程式時,保存自己的設定。 元件可以使用設定鍵,將多個元件執行個體的設定分開管理。

定義設定

應用程式設定結構會同時用於 ASP.NET 和 Windows Forms 中,而且包含在這兩個環境中共用的一些基類。 最重要的是 SettingsBase,它會透過集合提供設定的存取權,並提供低階方法來載入和儲存設定。 每個環境都會實作自己的類別,該類別是從 SettingsBase 衍生來的,以提供該環境的其他設定功能。 在以 Windows Forms 為基礎的應用程式中,所有應用程式設定都必須定義在衍生自 ApplicationSettingsBase 類別的類別上,這會將以下功能添加到基底類別中:

  • 較高層級的載入和儲存作業

  • 支援使用者範圍的設定

  • 將使用者的設定還原為預先定義的預設值

  • 從舊版應用程式升級設定

  • 在設定變更之前或儲存之前驗證設定

您可以使用 System.Configuration 命名空間內定義的數個屬性來描述設定;這些屬性描述於 應用程式設定屬性 中。 當您定義設定時,必須使用ApplicationScopedSettingAttribute或UserScopedSettingAttribute來套用設定,其描述了設定是適用於整個應用程式還是僅適用於目前的使用者。

下列程式碼範例定義了一個具有單一設定的自訂設定類別: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

設定持續性

ApplicationSettingsBase 類別本身不會自行保存或載入設定;這一工作屬於設定提供者,一個衍生自 SettingsProvider 的類別。 如果衍生類別ApplicationSettingsBase未透過SettingsProviderAttribute指定設定提供者,則會使用預設提供者LocalFileSettingsProvider。

原本隨 .NET Framework 一起發行的設定系統支援透過本機電腦的 machine.config 檔案,或在您部署應用程式時包含的 app.exe.config 檔案內提供靜態應用程式設定資料。 LocalFileSettingsProvider 類別會以下列方式擴充此原生支援:

  • 應用程式範圍的設定可以儲存在 machine.config 或 app.exe.config 檔案中。 Machine.config 永遠唯讀,而 app.exe.config 基於安全性考量,對大部分應用程式而言限制為唯讀。

  • 使用者範圍的設定可以儲存在 app.exe.config 檔案中,在此情況下視為靜態預設值。

  • 非預設的使用者範圍設定會儲存在一個名為 user.config 的新檔案中。您可以使用 DefaultSettingValueAttribute 來指定使用者範圍設定的預設值。 因為使用者範圍設定通常會在應用程式執行期間變更,user.config 一律是可讀寫的。 如需詳細資訊,請參閱 使用者範圍設定的儲存位置。

這三個組態檔全部以 XML 格式儲存設定。 應用程式範圍設定的最上層 XML 元素是 <appSettings>,而 <userSettings> 用於使用者範圍的設定。 含有應用程式範圍設定及使用者範圍設定的預設值的 app.exe.config 檔案如下︰

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

如需查看組態檔中應用程式設定區段的元素定義,請參閱應用程式設定文件架構。

設定繫結關係

應用程式設定使用 Windows Forms 資料繫結架構,提供設定物件和元件之間設定更新的雙向通訊。 如果您使用 Visual Studio 建立應用程式設定,並將它們指派給元件的屬性,則會自動產生這些繫結關係。

您只能將應用程式設定繫結至支援 IBindableComponent 介面的元件。 此外,元件必須實作特定系結屬性的變更事件,或透過 INotifyPropertyChanged 介面通知應用程式設定該屬性已變更。 如果元件未實作 IBindableComponent,且你透過 Visual Studio 繫結,繫結的屬性將在第一次時設定,但後續不會更新。 如果元件實作了 IBindingComponent,但不支援屬性變更通知,則在屬性變更時,該繫結不會在設定檔中更新。

某些 Windows Forms 元件,例如 ToolStripItem,不支援設定繫結。

設定序列化

當 LocalFileSettingsProvider 必須將設定儲存到磁碟時,它會執行下列動作:

  1. 使用反射來檢查您衍生類別上定義的所有屬性,找出那些套用有 ApplicationScopedSettingAttribute 或 UserScopedSettingAttribute 的屬性。

  2. 將屬性序列化至磁碟。 首先,將嘗試在類型相關聯的 TypeConverter 上呼叫 ConvertToString 或 ConvertFromString。 如果不成功,則改用 XML 序列化。

  3. 根據設定的屬性,判斷哪些設定在哪些檔案中。

如果您實作了自己的設定類別,您可以使用 SettingsSerializeAsAttribute 來標記二進位或自訂序列化的設定,使用 SettingsSerializeAs 列舉。 如需有關如何在程式碼中建立您自己的設定類別的詳細資訊,請參閱如何︰建立應用程式設定。

檔案位置設定

根據應用程式的安裝方式,app.exe.config 和 user.config 檔案的位置會有所不同。 對於複製到本機電腦的 Windows Forms 應用程式,app.exe.config 會位於應用程式主要可執行檔基底目錄的相同目錄中,而 user.config 將位於由 Application.LocalUserAppDataPath 屬性指定的位置。 對於透過 ClickOnce 安裝的應用程式,這兩個檔案都會位於 %InstallRoot%\Documents and Settings\使用者名稱\Local Settings 底下的 ClickOnce 資料目錄。

如果使用者已啟用漫遊設定檔,這些檔案的儲存位置會稍有不同,這可讓使用者在使用網域內的其他電腦時定義不同的 Windows 和應用程式設定。 在此情況下,ClickOnce 應用程式和非 ClickOnce 應用程式都會將其 app.exe.config 和 user.config 檔案儲存在 %InstallRoot%\Documents and Settings\username\Application Data 底下。

如需了解有關應用程式設定功能如何與新部署技術結合運作的詳細資訊,請參閱《ClickOnce 和應用程式設定》。 如需 ClickOnce 資料目錄的詳細資訊,請參閱存取 ClickOnce 應用程式中的本機和遠端資料。

應用程式設定和安全性

應用程式設定設計為在部分信任情況下運作,這是裝載於網際網路或內部網路上的 Windows Forms 應用程式預設的受限制環境。 使用應用程式設定搭配預設的設定提供者時,不需要任何超過部分信任的特殊權限。

當 ClickOnce 應用程式中使用應用程式設定時,user.config 檔案會儲存在 ClickOnce 資料目錄中。 應用程式 user.config 檔案的大小不能超過 ClickOnce 設定的資料目錄配額。 如需詳細資訊,請參閱 ClickOnce 和應用程式設定。

自訂設定提供者

在應用程式設定架構中,應用程式設定包裝類別(衍生自ApplicationSettingsBase)與其相關聯的設定提供者(衍生自SettingsProvider)之間具有鬆散耦合。 這個關聯僅由套用至包裝類別或其個別屬性的 SettingsProviderAttribute 來定義。 如果沒有明確指定設定提供者,則會使用預設提供者 LocalFileSettingsProvider。 因此,此架構支援建立和使用自訂設定提供者。

例如,假設您想要開發及使用 SqlSettingsProvider,此提供者會將所有設定資料儲存在 Microsoft SQL Server 資料庫中。 您的 SettingsProvider 衍生類別會在其 Initialize 方法中收到這項資訊,作為類型為 System.Collections.Specialized.NameValueCollection 的參數。 接著,您會實作 GetPropertyValues 方法,從資料存放區擷取您的設定,並實作 SetPropertyValues 加以儲存。 您的提供者可以使用SettingsPropertyCollection提供給GetPropertyValues來判斷屬性的名稱、類型和範圍,以及針對該屬性定義的任何其他設定屬性。

您的提供者需要實作一個屬性及一個方法,而其實作可能不容易理解。 ApplicationName 屬性是 SettingsProvider 的抽象屬性;您應該將其程式化為傳回以下內容:

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

您的衍生類別也必須實現 Initialize 方法,不接受任何引數,也不傳回任何值。 此方法不是由 SettingsProvider 定義。

最後,您會在提供者上實作 IApplicationSettingsProvider ,以支援重新整理設定、將設定還原為預設值,以及將設定從一個應用程式版本升級至另一個版本。

實作並編譯您的提供者之後,您必須指示設定類別使用此提供者來代替預設值。 您可以透過 SettingsProviderAttribute 來完成此作業。 如果套用至整個設定類別,則提供者將用於類別所定義的每一個設定;如果套用至個別設定,應用程式設定架構只會針對這些設定使用該提供者,對於其他的設定則使用 LocalFileSettingsProvider。 下列程式碼範例示範如何指示設定類別來使用您的自訂提供者。

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

一個提供者可供多個執行緒同時呼叫,但永遠寫入相同的儲存位置。因此,應用程式設定架構只會具現化提供者類別的單一執行個體。

這很重要

您應該確保您的提供者是執行緒安全的,並且一次只允許一個執行緒寫入配置檔案。

您的提供者不需要支援 System.Configuration 命名空間中定義的所有設定屬性,但至少必須支援 ApplicationScopedSettingAttribute 和 UserScopedSettingAttribute,並且應該支援 DefaultSettingValueAttribute。 對於不支援的屬性,您的提供者應該失敗且不需要通知,也就是不應該擲回例外狀況。 然而,如果 settings 類別使用了無效的屬性組合 — 例如將 ApplicationScopedSettingAttribute 和 UserScopedSettingAttribute 套用至相同的設定 — 您的提供者應該擲回例外狀況並停止作業。

另請參閱