構成ファイル取得でハマった (2)
さて、 (1) で無事成功したので、次にこれを共通ライブラリ化しようと企んだのですが、リスト形式の構成って結構使うので、折角だから Settings クラスまで共通化出来ないかな、と思ったのです。(これが混沌の始まり)
って事で、まずはこんな感じで書き換えてみました。
GenericListSettings.cs (元の AppDataSettings.cs )
using System; using System.Collections.Generic; namespace Jp.Mkns.Configuration { public class GenericListSettings<T> { private List<T> _items; public List<T> Items { get { if (this._items == null) { this._items = new List<T>(); } return this._items; } set { this._items = value; } } } }
んで、それに合わせてエントリポイントも書き換える。
ConfigurationTest.cs
using System; using System.Configuration; namespace Jp.Mkns.Configuration { class ConfigurationTest { static void Main() { GenericListSettings<AppData> settings = (GenericListSettings<AppData>)System.Configuration.ConfigurationManager.GetSection("AppDataSettings"); if (settings == null) { Console.WriteLine("取得失敗"); } else if (settings.Items.Count == 0) { Console.WriteLine("データが0件です!"); } else { foreach (AppData data in settings.Items) { Console.WriteLine(data.Name); } } } } }
構成ファイルも書き換えが必要、と。
app.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="AppDataSettings" type="Jp.Mkns.Configuration.XmlConfigurator, ConfigurationTest" /> </configSections> <AppDataSettings type="Jp.Mkns.Configuration.GenericListSettings`1[[Jp.Mkns.Configuration.AppData, ConfigurationTest]], ConfigurationTest"> <Items> <AppData Name="テストデータ1" /> <AppData Name="テストデータ2" /> <AppData Name="テストデータ3" /> </Items> </AppDataSettings> </configuration>
何気に type の書き方にも 10 分位迷いました。
さぁ実行! ……しかし
実行時に例外発生。発生箇所は XmlConfigurator.cs で Deserialize しているところ。エラーの内容は「 XML ドキュメントでエラーが発生しました。 <AppDataSettings xmlns=''> は指定できません。」
しばらく意味判らず。なんで「 Namespace は指定できない」なんて云うエラーが?
……で、 Google 先生に問いかけてみたところ、以下の様な話は出てくるもののいまいち判らず。
- File not found (aus-dotnet mailling list)
- Page Not Found | The Platform (.NET247)
仕方がないので小一時間程色々やってみたところ、どうも Deserialize の際に元の XML ドキュメントのキー (AppDataSettings) と格納するデータインスタンスのキー (AppDataSettings<T>) が一致しなくて落ちているらしい。
……なんじゃそりゃ。
これを回避するには……。
- GenericListSettings クラスに XmlAttribute(Name="AppDataList") 属性を付ける
- GenericListSettings クラスを普通のクラスにして Items プロパティの型を List<object> にする
ってところかしら。
でも、 1 は本末転倒(共通化出来てないし)、 2 はなんか微妙。(折角の Generic が台無し)
これ、他になんかいい手ないかなぁ。。。
……と云うところで今日は時間切れでした。誰かこのソリューションの良い解決策があったら教えてください。