2011年08月15日

アプリケーションの設定情報の扱いについて考えてみる(5)

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回説明したように、ApplicationSettingsBase では、
「ユーザ単位ではなく、アプリケーションで一つの設定情報を扱い、かつ、読み書きを可能にしたい」
という要求には独自のプロバイダーを記述する必要があります。
これ結構面倒です。

それならば、ConfigurationSection クラスという別のクラスを利用したほうが
簡単に要求に答えられそうです。

ということで、ConfigurationSection クラスを使い、ウィンドウの位置とサイズを扱うサンプルを
書いてみました。以下にそのコードを示します。


※ System.Configuration を参照に追加します。

クラス WindowInfoは、ConfigurationSection クラスから派生させています。
ApplicationSettingsBase から派生させたクラスと良く似ていますね。
大きく異なる点は、Load staticメソッドがある点です。
このメソッドは、設定ファイルを読み込むメソッドですが、標準の App.configではなく、
別ファイルとして、configファイルを扱えるようにようにしてます。
ここでは、"windowInfo.app.config" としています。

Saveメソッドは、インスタンスメソッドです。configファイルへの保存は、Configurationクラスの
Saveメソッドを呼び出すだけです。自分で保存ロジックを記述する必要はありません。

"windowInfo.app.config"の中身は、以下のようになります。
属性として値が保持されるので、ApplicationSettingsBase よりは、読みやすいですね。

なお、"windowInfo.app.config" は事前に用意しておく必要があります。
windowInfo要素は無くてもかまいません。存在しない場合は、DefaultValueで指定した
値が、セットされます。

最後に、利用する側のコード例を示します。



なお、ApplicationSettingsBaseとは異なり、バージョン管理を行いたいという場合には、 自分ですべて実装する必要があるようです。 一長一短がありますので、要求によって使い分ける必要がありますね。   

Posted by gushwell at 23:00Comments(0)TrackBack(0)

2011年07月26日

アプリケーションの設定情報の扱いについて考えてみる(4)

   このエントリーをはてなブックマークに追加 Clip to Evernote
「アプリケーションの設定情報の扱いについて考えてみる」の4回目です。

■ ApplicationScopedSettingAttribute

[UserScopedSetting] の代わりに、[ApplicationScopedSetting]属性を付加すると、 ユーザ単位ではなく、
アプリケーションでひとつの(つまり、すべてのユーザーに対して共通の) 値を持つことができます。

しかし、この属性を付けた場合は、デフォルトの動作(LocalFileSettingsProviderの動作)では、読み取り専用となります。
値を変更し保存することができません。

この読み取り専用の設定情報は、app.config に記述することになります。
以下に、その例を示します。


なお、これを書きこみ可能とするには、System.Configuration.SettingsProvider を継承した独自のプロバイダークラスを
作成する必要がありますが、この作成方法については、省略します。
興味あるかたは、MSDN等で調べてください。
  
Posted by gushwell at 23:00Comments(0)TrackBack(0)

2011年07月24日

アプリケーションの設定情報の扱いについて考えてみる(3)

   このエントリーをはてなブックマークに追加 Clip to Evernote
「アプリケーションの設定情報の扱いについて考えてみる」 の3回目です。

■ バージョンアップ時に前バージョンの情報を引き継ぐ

アセンブリのバージョンが上がったときは、configファイルの保存場所が変更されることは前回説明しました。
これは何を意味するかというと、そのままでは、前バージョンの設定情報を取得することができないということです。
Windowsのサイズと位置程度ならば、初期状態に戻ってしまってもかまわないかもしれませんが、設定情報を引き継ぎたいということは、良くあることです。
この目的のために、ApplicationSettingsBase には、Upgradeというメソッドが用意されています。

しかし、何を基準にUpgradeを呼び出したら良いのかを判断する方法が用意されていないようです。
※ 調べましたが、見つけることができませんでした。

そのため、自前でバージョンが変更されたかどうかを判断するコードを書く必要があります。

ここでは、IsUpgraded というプロパティを WindowInfoに追加することで対応します。


このプロパティを使った、設定情報の読み込みを以下に示します。


これで、設定情報の引継ぎが可能になります。

2011/8/9 追記
IsUpgradedプロパティのコードが間違っていましたので、訂正しました。
  
Posted by gushwell at 21:00Comments(2)TrackBack(0)

2011年07月18日

アプリケーションの設定情報の扱いについて考えてみる(2)

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回の続き

前回は、ApplicationSettingsBase クラスを継承した簡単なクラス定義例をお見せしました。
今回は、「デフォルト値の設定」と「保存場所とその形式」について簡単に解説します。

■ デフォルト値を設定する。

デフォルト値を設定するには、NullReferenceException 例外をキャッチし、そこで、値を設定する方法と、
属性でデフォルト値を設定する方法の2通りがあります。

属性でデフォルト値を設定するには、DefaultSettingValueAttribute 属性を指定します。

前回示したWindowInfoクラスを例に、そのコードを示します。


このようにすれば、設定ファイルが存在しない場合にも例外は発生しませんので、try-catchは不要になります。


■どこに保存されるのか

exeファイルが存在するフォルダをみても、それらしいファイルは存在していません。
では、どこに保存されているのかというと、Windows7では、


といった場所に保存されます。
アセンブリにCompanyNameが設定されていない場合は、exe名が CompanyNameになります。

1.0.0.0 は、アセンブリのバージョンを示します。
製品バージョンやファイルバージョンではなく、アセンブリのバージョンです。
アセンブリのバージョンが変わると、保存場所も変わります。
ビルド番号やリビジョン番号が変わっても保存場所は変わります。


■ 構成ファイルの形式

構成ファイルのサンプルを示します。

  
Posted by gushwell at 22:30Comments(0)TrackBack(0)

2011年07月10日

アプリケーションの設定情報の扱いについて考えてみる(1)

   このエントリーをはてなブックマークに追加 Clip to Evernote
■はじめに

アプリケーション独自の設定情報を扱いたい、そんな要求に答えるには、太古の昔は、INIファイルが定番でしたが、
いつしか、レジストリが主流になり、そして.NETでは、XML形式のconfigファイルへと移ってきました。

configファイルにアプリケーション独自の情報を設定するのに、もっとも手軽なのが、App.config の
要素を使う方法です。
ただ、これは、
・全てを文字列として扱う必要がある。
・項目を一つ一つ指定してアクセスする必要がある
など、柔軟性に欠ける部分があります。

そして、さらに問題となるのが、書き込みをしたいという要求にうまく対応できないということです。

そこで、数回にわけて、設定ファイルの読み書きについて考えてみます。

まずは、.NET Frameworkでそのために用意されていると思われるApplicationSettingsBaseクラス を使い、
アプリケーション独自の設定情報の読み書きについて考えてみます。

■ApplicationSettingsBaseクラスを利用した設定ファイルの読み書き

例えば、ウインドウのサイズと位置を保存しておきたいとしましょう。
当然、これらの値はひとつのクラスとして扱いたいですね。
例えば、


というクラスを考えてみます。
このクラスを 設定ファイルに保存できるようにするには、ApplicationSettingsBase から継承し、
以下のように書き換えてやる必要があります。


随分コードが増えてしまいましたが、パターン化されていますので、 機械的にコーディングできると思います。

このクラス定義ができれば、あとは読み書きのコードを書くだけです。


読み込みは、WindowInfo のオブジェクトを生成し、プロパティにアクセスするだけです。
なお、このプログラムを最初に起動した場合は、値を読み込むことが出来ないために、
NullReferenceException 例外が発生します。この例外が出たときには、何もせずにデザイン時の値を
そのまま使います。
書き込みは、WindowsInfoの各プロパティに値を設定し、Saveメソッドを呼び出します。

なお、WindowsFormsでは、フォームデザイナーのプロパティ画面で、(ApplicationSettings) で
保存したいプロパティを設定すれば、いちいち上記のようなコードを書く必要はありません。
あくまでも、サンプルとして見てください。

実際、自動生成される Settings.Designer.cs を見てみると、ApplicationSettingsBase クラスを継承したクラスが
定義されています。

もちろん、フォームやGUIコントロールのプロパティ以外の値を設定するには、デザイナーでのサポートは
ありませんので、ApplicationSettingsBaseクラスを利用するなら、ここに書いた方法で値を設定することになります。

(続く...)

追記 (2011/07/11)
最後の文は、ちょっと語弊がある文章でした。
C#プロジェクトの Properties フォルダの、Settings.settingsを開いて表示されるデザイナー(これもデザイナー
の一種ですね)で独自の情報を格納することができます。

ただ、このシリーズでは、Settings.settingsを開いて表示される設定デザイナーを利用する方法については、割愛します。

ApplicationSettingsBase を直接使ってみることで、Settings.settingsで作成する 設定ファイルクラスを
より理解できるようになります。

  
Posted by gushwell at 22:38Comments(0)TrackBack(0)

2010年03月17日

ApplicationSettingsBaseクラス

   このエントリーをはてなブックマークに追加 Clip to Evernote
構成設定ファイルを扱う場合に、ApplicationSettingsBaseクラスって、とても良くできたクラスだと思うんだけど、
UserScopedSettingAttribute ではなく、ApplicationScopedSettingAttribute を付加した場合って、書き込みが出来ないんですね。

ApplicationScoped でも、設定ファイルに書き込みがしたいって要求はないのかな?
LocalFileSettingsProvider ではなく、自分で新たなプロバイダを書けばいいのだけれど、結構面倒そうだ。

それと、バージョン番号が違うと別のフォルダに保存してしまうという動作を変更できないのは、どうなんだろう
Upgradeメソッドがあるから、大抵は別フォルダにあっても問題ないのだろうけど、自分でバージョンコントロールを行いたいときにそれを変更する手段が無いのは困る。
こちらは、独自プロバイダーを書いても対応できないようだ。

それと、保存先を決定するバージョンが、アセンブリのバージョンっていうのも戸惑った。
ApplicationScoped の項目だけレジストリに書くような拡張をしようと思って、壁に突き当たった。
だって、Application.CommonAppDataRegistryで採用しているバージョンはProductVersionなんだもの...

結局、ApplicationSettingsBaseから派生させるのではなく、 ConfigurationSection から独自のSectionクラスを派生させて、 ConfigurationManager をラップした独自のApplicationSettingsクラスを 書いたほうが良さそうな気がしてきた。
  
Posted by gushwell at 23:27Comments(0)TrackBack(0)