アプリケーション設定アーキテクチャ
このトピックでは、アプリケーション設定アーキテクチャのしくみについて説明し、グループ設定や設定キーなど、アーキテクチャの高度な機能についても解説します。
アプリケーション設定アーキテクチャにより、アプリケーション スコープまたはユーザー スコープを使用して厳密に型指定された設定の定義や、アプリケーション セッション間における設定の永続化がサポートされます。 また、このアーキテクチャによって、ローカル ファイル システムとの間で設定を保存したり、設定を読み込んだりするために使用する、既定の永続化エンジンが提供されます。 さらに、このアーキテクチャは、カスタムの永続化エンジンを指定するためのインターフェイスも定義します。
カスタム コンポーネントがアプリケーションにホストされる際に、そのコンポーネントの独自の設定を永続化できるようにするインターフェイスが提供されます。 設定キーを使用することにより、コンポーネントでそのコンポーネントの複数のインスタンスの設定を区別できます。
設定の定義
アプリケーション設定アーキテクチャは、ASP.NET および Windows フォームの内部で使用され、この両方の環境で共有される多くの基本クラスを含みます。 最も重要な基本クラスは SettingsBase であり、コレクションを介した設定へのアクセスと、設定を読み込んだり保存したりするための下位のメソッドを提供します。 各環境は、SettingsBase から派生した独自のクラスを実装し、その環境用の追加の設定機能を提供します。 Windows フォーム ベースのアプリケーションでは、次に示すような機能を基本クラスに追加する ApplicationSettingsBase クラスの派生クラス上で、すべてのアプリケーション設定を定義する必要があります。
高水準の読み込み操作および保存操作
ユーザー スコープの設定のサポート
ユーザー設定から定義済み既定値への復帰
以前のバージョンのアプリケーションで使用した設定のアップグレード
設定の変更前または保存前における検証
設定は、System.Configuration 名前空間内で定義されている数多くの属性を使用して表すことができます。これらの属性については、「アプリケーション設定の属性」を参照してください。 設定を定義する際は、ApplicationScopedSettingAttribute または UserScopedSettingAttribute のいずれかを使用して設定を適用する必要があります。これにより、その設定がアプリケーション全体に適用されるか、または現在のユーザーにだけ適用されるかが指定されます。
次のコード例では、 BackgroundColor という単一の設定を持つカスタム設定クラスを定義します。
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
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;
}
}
}
設定の永続化
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 という新しいファイルに格納されます。user は現在このアプリケーションを実行しているユーザーの名前です。 ユーザー スコープの設定の既定値は、DefaultSettingValueAttribute を使用して指定できます。 ユーザー スコープの設定はアプリケーションの実行時に変更されることがよくあるため、user.config は常に読み取り/書き込み用となります。
この 3 つの構成ファイルはいずれも XML 形式で設定を格納します。 アプリケーション スコープの設定の最上位 XML 要素は、<appSettings> で、ユーザー スコープの設定の最上位 XML 要素は <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 フォーム データのバインディング アーキテクチャを使用し、設定オブジェクトと設定コンポーネントの間で、設定の更新を双方向で通信します。 Visual Studio を使用してアプリケーション設定を作成し、その設定をコンポーネントのプロパティに割り当てる場合、このバインディングは自動的に生成されます。
IBindableComponent インターフェイスをサポートするコンポーネントに対しては、アプリケーション設定のバインド以外は実行できません。 また、コンポーネントでは、特定のバインドされたプロパティに変更イベントを実装するか、INotifyPropertyChanged インターフェイスを使用してプロパティの変更をアプリケーション設定へ通知する必要があります。 コンポーネントで IBindableComponent を実装せずに Visual Studio を使用してバインドした場合、バインドされたプロパティは初回のみ設定されますが、更新されません。 コンポーネントが IBindableComponent を実装してもプロパティの変更通知をサポートしていない場合、プロパティが変更されたときに設定のバインディングは更新されません。
ToolStripItem など、一部の Windows フォーム コンポーネントは、設定のバインディングをサポートしていません。
設定のシリアル化
LocalFileSettingsProvider がディスクに設定を保存する必要がある場合、次のような処理を実行します。
リフレクションを使用して、ApplicationSettingsBase 派生クラスで定義されているすべてのプロパティを調べ、ApplicationScopedSettingAttribute または UserScopedSettingAttribute を使用して適用されたプロパティを見つけます。
プロパティをディスクにシリアル化します。 まず、型に関連付けられている TypeConverter に ConvertToString または ConvertFromString を呼び出そうとします。 これが成功しない場合、代わりに XML シリアル化を使用します。
設定の属性に基づいて、どの設定がどのファイルに指定されているかを判断します。
独自の設定クラスを実装している場合、SettingsSerializeAsAttribute で SettingsSerializeAs 列挙値を使用して、バイナリのシリアル化またはカスタムのシリアル化の設定にマークを付けることができます。 コードで独自の設定クラスを作成する方法の詳細については、「方法 : アプリケーション設定を作成する」を参照してください。
設定ファイルの場所
app.exe.config ファイルおよび user.config ファイルの場所は、アプリケーションのインストール方法によって異なります。 Windows フォーム ベースのアプリケーションをローカル コンピューターにコピーした場合、app.exe.config はアプリケーションのメインの実行可能ファイルのベース ディレクトリと同じディレクトリに配置され、user.config は Application.LocalUserAppDataPath プロパティで指定した場所に配置されます。 アプリケーションを ClickOnce を使用してインストールした場合、どちらのファイルも %InstallRoot%\Documents and Settings\username\Local Settings の下にある ClickOnce のデータ ディレクトリに配置されます。
ユーザーがローミング プロファイルを有効にしている場合、これらのファイルの格納場所はわずかに異なります。ローミング プロファイルでは、ユーザーがドメイン内の別のコンピューターを使用する際に Windows とアプリケーションに対して異なる設定を定義できます。 この場合、ClickOnce アプリケーションも ClickOnce 以外のアプリケーションも、app.exe.config ファイルおよび user.config ファイルが %InstallRoot%\Documents and Settings\username\Application Data に格納されます。
アプリケーション設定機能と新しい配置テクノロジの連携の詳細については、「ClickOnce とアプリケーション設定」を参照してください。 ClickOnce のデータ ディレクトリの詳細については、「ClickOnce アプリケーションにおけるローカル データおよびリモート データへのアクセス」を参照してください。
アプリケーション設定とセキュリティ
アプリケーション設定は部分信頼で機能するように設計されています。部分信頼とは、インターネット上やイントラネット上でホストされる Windows フォーム アプリケーションにとって既定となる制限された環境のことです。 既定の設定プロバイダーと共にアプリケーション設定を使用する場合、部分信頼以外に特別なアクセス許可は必要ありません。
ClickOnce アプリケーション内でアプリケーション設定を使用する場合、user.config ファイルは ClickOnce のデータ ディレクトリに格納されます。 アプリケーションの user.config ファイルのサイズを、ClickOnce で設定したデータ ディレクトリ クォータより大きくすることはできません。 詳細については、「ClickOnce とアプリケーション設定」を参照してください。
カスタム設定プロバイダー
アプリケーション設定アーキテクチャでは、ApplicationSettingsBase から派生したアプリケーション設定ラッパー クラスと、SettingsProvider から派生した、1 つまたは複数の関連するプロバイダーとの間には緩い結合があります。 この結合は、ラッパー クラスまたはその個々のプロパティに適用されている SettingsProviderAttribute によってのみ定義されます。 設定プロバイダーを明示的に指定しないと、既定のプロバイダーである LocalFileSettingsProvider が使用されます。 したがって、このアーキテクチャではカスタム設定プロバイダーの作成と使用がサポートされていることになります。
たとえば、すべての設定データを Microsoft SQL Server データベースに格納するプロバイダーである SqlSettingsProvider を使用するとします。 SettingsProvider 派生クラスは、この情報を System.Collections.Specialized.NameValueCollection 型のパラメーターとして Initialize メソッドで受け取ります。 次に、GetPropertyValues メソッドを実装して、設定値をデータ ストアから取得し、SetPropertyValues を使用して保存します。 このプロバイダーは、GetPropertyValues に指定される SettingsPropertyCollection を使用して、プロパティの名前、型、スコープや、このプロパティに対して定義されたその他の設定属性を判断します。
このプロバイダーでは、1 つのプロパティと 1 つのメソッドを実装する必要がありますが、この実装はわかりにくいことがあります。 ApplicationName プロパティは、SettingsProvider の抽象プロパティです。次のような値を返すようにプログラムする必要があります。
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.
}
}
また、派生クラスは、引数を受け取らず値を返さない Initialize メソッドも実装する必要があります。 このメソッドは SettingsProvider によって定義されません。
最後にプロバイダーに IApplicationSettingsProvider を実装して、設定の更新、設定値から既定値への復帰、およびアプリケーションのあるバージョンから別のバージョンへの設定のアップグレードをサポートします。
カスタム プロバイダーの実装とコンパイルを行った後、設定クラスに対して、既定のプロバイダーではなくこのプロバイダーを使用するように指示する必要があります。 これには、SettingsProviderAttribute を使用します。 設定クラス全体にこのプロバイダーを適用した場合、このプロバイダーはこのクラスが定義する各設定に対して使用されます。個々の設定に適用した場合、アプリケーション設定アーキテクチャは、該当する設定に対してのみこのプロバイダーを使用し、それ以外の設定については LocalFileSettingsProvider を使用します。 次のコード例では、設定クラスに対してカスタム プロバイダーを使用するように指示する方法を示します。
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.
}
}
複数のスレッドから同時にプロバイダーを呼び出すことができますが、プロバイダーは常に同じストレージの場所に書き込みを行います。したがって、アプリケーション設定アーキテクチャによってインスタンス化されるカスタム プロバイダー クラスは 1 つだけです。
重要
カスタム プロバイダーがスレッド セーフであり、構成ファイルへの書き込みを実行できるのは一度に 1 つのスレッドだけであることを確認しておく必要があります。
カスタム プロバイダーは System.Configuration 名前空間で定義されているすべての設定属性をサポートする必要はありませんが、少なくとも ApplicationScopedSettingAttribute、UserScopedSettingAttribute、および DefaultSettingValueAttribute をサポートしている必要があります。 サポートしていない属性については、カスタム プロバイダーは警告なしに失敗し、例外をスローしません。 ただし、設定クラスが無効な属性の組み合わせを使用した場合 (同じ設定に ApplicationScopedSettingAttribute と UserScopedSettingAttribute を適用するなど)、カスタム プロバイダーは例外をスローし、操作が中断されます。