ASP.NET で開発していて毎回思うのが、設定を Web.config に持たせた時のコードからの扱いにくさです。例えば以下のように appSettings セクションに設定を追加します。
<appSettings> <add key="Foo" value="123" /> <add key="Bar" value="456" /> <add key="Baz" value="789" /> </appSettings>
実際にコードからこの設定を読み込もうとすると、以下のように冗長なコードを書く必要があります。
特にキーが文字列で指定しないといけないのが間違いの元ですし、非常にイケてないですよね。
// キーを文字列で指定しないといけない var foo = ConfigurationManager.AppSettings["Foo"]; var bar = ConfigurationManager.AppSettings["Bar"]; var baz = ConfigurationManager.AppSettings["Baz"];
これだとインテリセンスも効かないですし、実際に使う時にめんどくさいですよね。
個人的には以下のようにクラスとして扱いたいわけです。これなら普通のクラスなのでインテリセンスが効くので、キー名の打ち間違いは起こらなくなります。
public static class AppSettings { public static string Bar { get { return ConfigurationManager.AppSettings["Bar"]; } } public static string Baz { get { return ConfigurationManager.AppSettings["Baz"]; } } public static string Foo { get { return ConfigurationManager.AppSettings["Foo"]; } } }
という訳で、良い感じに Web.config の appSettings セクションを読み込んでクラスにしてくれる T4 を書きました。
説明は省きますが、プロジェクト内の Web.config を読み込んでプロパティとして出力しているだけです。
<#@ template debug="true" hostspecific="true" language="C#" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.Configuration" #> <#@ import namespace="System.Configuration" #> <#@ import namespace="System.Linq" #> <#@ output extension=".cs" #> <# var namespaceName = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint").ToString(); var configFile = new ExeConfigurationFileMap(); configFile.ExeConfigFilename = Host.ResolvePath("Web.config"); var config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None); var appSettings = config.AppSettings.Settings; #> using System.Configuration; namespace <#= namespaceName #> { public static class AppSettings { <# foreach (var key in appSettings.AllKeys.OrderBy(p => p)) { #> public static string <#= key #> { get { return ConfigurationManager.AppSettings["<#= key #>"]; } } <# } #> } }
このテンプレートが実行されると、例にあげたような AppSettings クラスが生成されます。
これで自動的にクラスとして吐き出してくれるので、便利に使えるようになりました。