2015年3月12日

設定ファイル <appSettings> の 1 キーに複数値を設定

設定ファイル(app.config/web.config)の <appSettings> セクションで、キー 1 つに対して複数の値を設定したい場合がよくある。
そういう場合、ConfigurationSection を自作するのが一般的だと思われるが、実装が面倒だし、構成が異なるセクションに対して使いまわせるわけでもない。
複雑な設定値に対しては有効だが、簡単な設定値(数列など)に対しては過剰すぎる。

同じキーの <add> を複数記述しても、複数値を設定できない。
<add> なのに複数追加でないのは納得しにくい・・・というかネーミングが悪い。
[設定ファイル]

<configuration>
  <appSettings>
    <add key="numbers" value="1" />
    <add key="numbers" value="2" />
    <add key="numbers" value="3" />
  </appSettings>
</configuration>
[読取処理]

var numbers = ConfigurationManager.AppSettings.GetValues("numbers");

foreach( var number in numbers ) Console.WriteLine(number);
// 3
// ※最後の値しか入っていない
ConfigurationManager.AppSettings の型は NameValueCollection

また、<appSettings> セクションの動作は、.NET 1.1 なら IConfigurationSectionHandler を実装してカスタマイズできたが、.NET 2.0 以降は使用できなくなっている。(<add> の挙動を NameValueCollection.Add に変更するカスタマイズ例

CSV で設定

配列データの場合、CSV(カンマ区切り値)が最もシンプルに設定できる。

[設定ファイル]

<configuration>
  <appSettings>
    <add key="numbers" value="1,2,3" />
  </appSettings>
</configuration>
[読取処理]

// null 未考慮
var numbers = ConfigurationManager.AppSettings["numbers"].Split(',');

foreach( var number in numbers ) Console.WriteLine(number);
// 1
// 2
// 3

JSON で設定

配列よりも複雑なデータを設定したい場合(名前付きのデータなど)、JSON が便利である。
※JSON のデシリアライズには Json.NET がオススメ。(.NET 標準のものより簡単・便利なので)

[設定ファイル]

<configuration>
  <appSettings>
    <add key="ageRange" value="{'Min':10, 'Max':20, 'Name':'AgeRange'}" />
  </appSettings>
</configuration>
[読取処理]

//---- クラス定義 ----//
public class RangeInfo
{
    public int Min { get; set; }
    public int Max { get; set; }
    public string Name { get; set; }
}

//---- 以降はメソッド内で ----//
// null 未考慮
var ageRange = JsonConvert.DeserializeObject<RangeInfo>(
    ConfigurationManager.AppSettings["ageRange"]
);

Console.WriteLine(ageRange.Min);  // 10
Console.WriteLine(ageRange.Max);  // 20
Console.WriteLine(ageRange.Name); // AgeRange

クラスのシリアライズ/デシリアライズなら、XML やバイナリでも可能だが、XML の属性値に入れて運用することを考えると、今のところ JSON がベスト。
Json.NET ならシングルコーテーション「'」が使えることも大きい。

0 件のコメント:

コメントを投稿