WebMatrix 3:SwissKnife.T4.AppSettings を使う

執筆日時:

f:id:daruyanagi:20130406123715p:plain

Web.config の appSettings セクションをもとにクラスを生成してくれる T4 テンプレート SwissKnife.T4.AppSettings がよさげなので、これが WebMatrix 3 も使えないかなぁ、といろいろ試してみた。

アプローチその壱:Visual Studio の助けを借りる

SwissKnife.T4.AppSettings をインストールし、Web.config を編集して Web サイトを実行するだけでは動かなかったので(まぁ、そうだろうね!)、WebMatrix から Visual Studio を召喚してなんとかならないかな、というのが最初のアプローチ。Visual Studio には T4 を扱うためのメニューが用意されているはずだ。

しかし――

f:id:daruyanagi:20130406123939p:plain

あれれ。メニューがない。

f:id:daruyanagi:20130406124028p:plain

一度 NuGet を削除して、Visual Studio で新たに T4 テンプレート を作成すると[すべての T4 テンプレートの変換]というメニューが出るのだが。

この方法は諦めた。

アプローチその弐:TextTransform.exe を使う

f:id:daruyanagi:20130406124728p:plain

しょうがないので、Generating Files with the TextTransform Utility - Visual Studio 2015 | Microsoft Docs を参考に TextTransform.exe を利用したテンプレートの変換を試みる。

ちなみに、こいつは Visual Studio Professional 以上が必要なようだ。Visual Studio 2012 Express for Web をインストールしただけでは

C:\Program Files (x86)\Common Files\Microsoft Shared\TextTemplating\11.0

に TextTransform.exe が追加されない。

ごくごく簡単なバッチを書いて、必要な時に叩くようにしよう。

"Path\To\TextTransform.exe" -out AppSettings.cs AppSettings.tt

pause

するとエラーが出る。

c:\Users\Hidetoshi Yanagi\AppData\Local\Temp\AppSettings.tt(10,0) : error
: 変換を実行しています
: System.NullReferenceException
: オブジェクト参照がオブジェクトインスタンスに設定されていません。
場所 Microsoft.VisualStudio.TextTemplating46c835e8a19f4e3d880d23699cc45057
.GeneratedTextTransformation.TransformText() 場所 c:\Users\Hidetoshi Yanagi\
AppData\Local\Temp\AppSettings.tt:行 10

WebMatrix:NuGet サーバーをたてる - だるろぐ でもぶち当たった、ASP.NET Web Pages で名前空間が取得できない問題と同じようなことが起こっているようだ。あまり NuGet で取得したコードに手を加えたくはないが、10行目を修正する。

//var namespaceName = System.Runtime.Remoting.Messaging
//    .CallContext.LogicalGetData("NamespaceHint").ToString();
var namespaceName = "ASP";

とりあえずこれで動かすことはできた。IntelliSense でバリバリ AppSettings が呼べるぞー。

f:id:daruyanagi:20130406125526p:plainf:id:daruyanagi:20130406125530p:plain

蛇足

んー、それにしてもこの問題、なんとかうまく解決できないのかな? たとえば、名前空間が取れなかったときを ASP.NET Web Pages で決め打ちできるならば(あまりよくない実装だけど)、

var ns = System.Runtime.Remoting.Messaging
.CallContext.LogicalGetData("NamespaceHint");
var namespaceName = ns == null ? "ASP" : ns.ToString();
var templateFileName = Path.GetFileNameWithoutExtension(Host.TemplateFile);

みたいな感じでもいいのかもしれない。

追記

f:id:daruyanagi:20130406132244p:plain

AppSettings.cs は ~/App_Code フォルダに収めなきゃいけないのを忘れていた。WebMatrix で App_Code フォルダを作成し、バッチを以下のように書き換えて実行してね!

"Path\To\TextTransform.exe" -out ./App_Code/AppSettings.cs AppSettings.tt

pause