2007年5月14日月曜日

.NET アプリケーション設定ファイル ~プロジェクト間で共有 その1~

プロジェクトのプロパティの設定タブでアプリケーションの設定を行うことができます。
アプリケーションの設定にはアプリケーションスコープとユーザースコープの2種類があります。

アプリケーションスコープはアプリケーション全体の設定で読み取り専用です。
ユーザースコープはログインユーザごとの設定で読み書き可能です。

プロジェクトの設定プロパティで設定を行うと、同プロジェクトの「My Project」フォルダ内に「Settings.settings」ファイルが自動で作成されます。全てのファイルを表示を選択しないと見れません。また同プロジェクト内にapp.configがなければapp.configファイルが作成されます。

Settings.settingsファイルのSettings.Desiner.vbを見てもらうとわかりますが、このファイルはSystem.Configuration.ApplicationSettingsBaseから派生したMySettingsクラス定義ファイルでMy.MySettings.Default.設定名で設定内容にアクセスするためのクラスです。実際の設定内容はapp.configに保存されます。System.Configuration.ApplicationSettingsBaseクラスはapp.configに簡単にアクセスするために用意されたクラスです。詳しくは「アプリケーション設定ファイル」でググってくださいね。


実際に使用するといくつか問題がありました。
My.MySettings.Default.設定名でアクセスできるのは設定を行ったプロジェクト内のクラスでのみです。以下のようなソリューション構成の場合、共通プロジェクトで行った設定内容は共通プロジェクト内のクラスからはMy.MySettings.Default.設定名でアクセスできますが、AプロジェクトやBプロジェクトからはアクセスできません。

またWindowsアプリケーション(以下のStartUpプロジェクト)にアプリケーション設定を行った場合、インストール時にapp.configはexeファイルと同じフォルダにアプリケーション名.exe.configという名前で保存されます。しかしクラスライブラリ(以下の共通、A、Bプロジェクト)にアプリケーション設定を行った場合、インストール時にapp.configはdll内に取り込まれてexeファイルと同じフォルダにconfigファイルは作成されません。これではインストール後に設定ファイルの内容を変更するためには再度dllを作成し配布しなければなりません。

ソリューション
|
|-StartUpプロジェクト(Windowsアプリケーション)
| 
|  参照設定:共通プロジェクト、Aプロジェクト、Bプロジェクト
|
|-共通プロジェクト(クラスライブラリ)
|
|-Aプロジェクト(クラスライブラリ 
|  参照設定:共通プロジェクト
|
|-Bプロジェクト(クラスライブラリ)
|  参照設定:共通プロジェクト


どうすればいいのか、かなり悩みました。

まず最初に試した方法ですが、
StartUpプロジェクトにアプリケーション設定を行います。
するとStartUpプロジェクトにapp.configとSettings.settingが作成されます。
Settings.Desiner.vb(MySettingsクラス)を見るとスコープがFriendです。単純にこれをPublicにすれば外部公開できますね。でもこの方法では設定を変更する度にFriendクラスに戻ってしまいます。その上、AプロジェクトからStartUpプロジェクトのMySettingsクラスにアクセスするためには、Aプロジェクトの参照設定にMainプロジェクトを追加しなければなりません。う~ん循環参照ですね。

次に試した方法ですが、この方法で外部プロジェクトからも参照設定可能です。
StartUpプロジェクトにアプリケーション設定を行います。
するとStartUpプロジェクトにapp.configとSettings.settingが作成されます。
それから共通プロジェクトにSettingsReaderクラスを作成します。
このクラスにSystem.Configuration.ApplicationSettingsBaseの受け渡しをする静的プロパティを用意します。そしてStartUpプロジェクトのスタートアップオブジェクトであるSub MainからSettingReaderのプロパティにMy.MySetting.Defaultを渡してあげます。

StartUpプロジェクトのプロパティより設定タブを選択し以下のような設定を追加します。
【設定1】
名前:ProviderName
型:String
スコープ:アプリケーション
値:System.Data.OracleClient
【設定2】
名前:ConnectionString
型:(接続文字列)
スコープ:アプリケーション
値:Data Source=xxx;User ID=xxx;Password=xxx;
【設定3】
名前:FormBackColor
型:System.Drawing.Color
スコープ:ユーザー
値:255, 255, 192


共通プロジェクト.SettingReader.vb

Public Class SettingReader


 

    Private Shared p_SettingInstance As _

                Global.System.Configuration.ApplicationSettingsBase


 

    Public Shared Property SettingInstance() As _

                Global.System.Configuration.ApplicationSettingsBase

        Get

            Return p_SettingInstance

        End Get

        Set(ByVal value As Global.System.Configuration.ApplicationSettingsBase)

            p_SettingInstance = value

        End Set

    End Property


 

    '--Application Scope--

    '--Application Scopeは Getterのみ記述--


 

    Public Shared ReadOnly Property ProviderName() As String

        Get

            Return CType(p_SettingInstance.Item("ProviderName"), String)

        End Get

    End Property


 

    Public Shared ReadOnly Property ConnectionString() As String

        Get

            Return CType(p_SettingInstance.Item("ConnectionString"), String)

        End Get

    End Property


 

    '--UserScope--

    '--UserScopeは Getter Setterを記述--


 

    Public Shared Property FormBackColor() As System.Drawing.Color

        Get

            Return CType(p_SettingInstance.Item("FormBackColor"), System.Drawing.Color)

        End Get

        Set(ByVal value As System.Drawing.Color)

            p_SettingInstance.Item("FormBackColor") = value

        End Set

    End Property


 

End Class


StartUpプロジェクト.Main.vb

Public Class Main


 

    Public Shared Sub Main()

        Common.SettingReader.SettingInstance = My.MySettings.Default

        Application.Run(New Form1())

    End Sub


 

End Class

0 件のコメント: