テーマ設定してるとグチャグチャっすね。colorsフォーラム見てみたら、白バックのデフォルトテーマに戻せと書いてるけど、日本語版のVSだからか、「ツール>オプション>環境>フォントおよび色>テキストエディタ・表示項目」にそんな選択肢がそもそも出てこなかったり。無料だし、それもやむなし。いえば、CommunityエディションだとIntelliSenceも使えないんだった。インストールする意味がまるでなかった。結局↓こんな素っ気ない画面で。T4の使い方は前にどこかで読んだことがあったから、細かい仕様的なのは無視。#>で囲まれてる部分がテンプレート処理部。テンプレート内で参照出来る変数を下の方で宣言してて、その辺にいろいろコードがあるはずなので、そこら辺中心にチェックで。MVCに関する投稿デス。アセンブリ内をリフレクションでグルグル処理してるんだろーなと、たかをくくってたらこれが全然違うのね。CodeFunction2って誰ちゃん?CodeElementインターフェースってどこからはえてきたの?みたいな。Studioオートメーションってことらしい。クラスの定義をpartialにしたり、関数定義をvirtualにしたり、ソースをいじるのにそうしとかないと面倒なことになるからなんだろうね。そんな物の存在を全然知らなくてたまげたけど、使う部分はちょびっとだけなんだから気にせず読み進める。Controllers変数の中にControllerInfoのコレクションが入ってて、ControllerInfo.ActionMethodsの中にActionMethodInfoのコレクションが入ってるんだって。それらコレクション達を見ながらコード部を生成させる仕組み。今回はActionNameAttributeが宣言されてれば、アクション名をそっちに切り替えるってことをしたいので、ActionMethodInfoあたりを中心にチェック。思ったけど、オリジナルのアクション名が消えるとちょっと分かりにくいかも?オリジナル+ActionName指定の両方を展開しといたほうが、優しさチラリな気がしたので、そういう事にします。CodeFunctionのNameを書き換えるのは無理なんだろうから、ActionNameが指定されてるならそっちの名前を返すように内部のクラスを書き換える。}}太字の部分が追加したコードです。このクラスを派生させてる部分も同じように変える。IsOverrideって言うのが追加されてるのは、Controllerの書き換えをされる時に、アクション関数はすべてvirtualになって、そのControllerを内部で派生させて、すべてのアクションをoverrideしてるから。今回追加するActionNameで指定したアクション関数はそもそもそんな名前でControllerには存在しないから、派生クラスでしか不要だし、overrideするものじゃ無いじゃないですか。ここでそのフラグを保持しておいて、テンプレート処理部でこれを見て、overrideを付加するかどうか判定させるって感じです。続いて、ActionMethodsコレクションを構築しているProcessControllerActionMethodsを書き換える。ActionNameAttributeを見てそっちも追加する。オリジナルが不要なら↑のAddを削除。なんか、リフレクションじゃないから属性とか属性パラメータの取り方がちょっと特殊。基本すべてソースコードを解析した結果構築されるオブジェクト達だから中身は単なる文字列。arg.Valueで取り出したActionNameに指定してるName値がソース上で定義されてるのと同じようにダブルクォーテーション付きになってるので、そこを削除。最後にテンプレート部で処理してる部分を書き換え。#>}まずはMVCクラスの部分でオリジナルControllerクラスを入れ物にしてたから、テンプレートで生成した派生クラスになるように変更。しないとActionName名のアクション関数が無いから困るんです。}}上記太字の部分で最後です。無駄にソースを引用してるんで、長いですけど、実質10行ほどじゃないっすかね。思ったより、変更箇所も少なくて助かりました。Studioオートメーション&T4の組み合わせ恐るべし。すると、前回の投稿ではIntelliSenceに出てこなかったActionName指定の部分も出てくるようになりました。やったね!これまた興味ある方はダウンロードどうぞ(T4MVC-T.ttに名前変えてます)。MVCでは文字列(マジックストリング)を指定して、リンクやURLを生成するのが普通ですね。%>例えば、↑こんな感じで書くと↓こんな感じの出力に。</form>リンクの場合もそう。%>↑こんな感じでしょう。URL生成はコントローラとアクションを指定したり、ルーティング名を指定したりするのが、今までのオーソドックスな書き方。そんな状況は誰も嬉しくないよ!だってアクション名変えたら、指定してる箇所全部検索して変更しなきゃ行けないし、1文字でも間違ってたらちゃんと出力してくれない。そもそもの始まりは↓ここからでした。LinksBuildProviderを使ってASP.NET実行時に、CodeDom使ったコンパイラを走らせてがんばる方法(自アセンブリをリフレクションで探索)。応用しにくいっていうか、コードが書きにくい感じで、その時はそれほど便利でもないかな~、なんて油断してました。それでも、この時点でHtmlHelperを拡張して、文字列指定じゃなくて関数指定でリンク生成出来てました。この辺でPhilさんもエントリ上げてて、ActionNameで別名使ったときにこれだと対応出来ないから、その辺上手いこと処理出来るのを次のバージョンに向けて考えてます的なことを言ってた気がする。その後、いろいろ試行錯誤があって、出てきたのが↓これですよ。templateCodeDomじゃなくてT4でいいんじゃね?と気がついたんでしょうか。コード生成するならこういうテンプレートエンジン使った方が断然生産性が高いしね。このときはまだMvc-CodeGenっていう名前だったんですが、これを更にブラッシュアップして出てきたのが↓。fixesちょっとバージョンアップしたんだけど、T4MVCに名前変わってからはMVCのソースが公開されてるCodePlexに組み込まれました(アドインだからこういう言い方はおかしいかも?)。Sourceドキュメントなんてかけらもないので、どういう物かはソースを見て判断しましょう。TTファイルの最初に書かれてる内容がそのままなんですけどね。自分のMVCプロジェクトのルートにT4MVC.ttをコピー。後はT4なんで勝手にコード生成してコンパイルしてくれるので、すぐに使い始められます(最初にApp_Codeに放り込んでみたら全然動かなくてビックリした)。大枠でMVCという静的クラスが生成されて、そこからたどっていく感じになります。ASP.NETでも自動生成されるグローバルクラスにASPっていうのがあるけどそれと同じような感覚ですね。最初に書いたサンプルをT4MVCで書くとどうなるか、ですが、↓こうです。%>リンクに表示する部分以外のマジックストリングが無くなりました。このMVCクラスは動的なので、アクションやコントローラの名前を変更したら、コンパイルエラーが起きるので、変更し忘れともおさらばですよ!素敵です。これだけじゃなくてデスね、Linksというクラスも同時に生成されるんですが、そこにはContentフォルダとScriptsフォルダに含まれてるファイル達のリンクが生成されます。ここでActionNameAttributeをつけたアクションはちゃんと指定出来るのか気になるところなので、簡単に実験してみましょう。}こんなのを作成してみる。保存したりすると、勝手にT4MVCが動く。ViewでIntelliSenceをきかせてみると~?残念!ActionNameまでは見てくれませんでした。Index2が出てくるのを期待したんだけど。実行結果も残念ながら。元の名前のままでした。がんばって自分でtt書き換えてActionName属性を見るようにするか、おとなしく新しいバージョンを待つか。どっちが男らしい?ところで、このT4MVCを実行するとすべてのコントローラはpartialクラスになって、すべてのアクションはvirtualが自動でくっつきます。してかというと、ActionResultを引数に受け取るHtmlHelper拡張に渡して、URLを生成しやすくするためですよね。内部で独自クラスに派生させたコントローラを生成し、アクションをオーバーライドしてるんですね。コントローラ書き換えられるのが気持ち悪い!って人にはお勧めしないですけど...。T4わんまるとキャプテンわん横浜開港150周年記念キャラクターのたねまる。最近まで知らなかったけどこんなのいたのか。電車の車体に貼られてるのを見て知った。まるドットコム|横浜開港150周年マスターライセンシーオフィス公式サイトそして、どうやら彼女がいるらしい...。まるとか適当な名前で教えられたけど、これも横浜がらみ。ハマスポのキャラクターらしい。「落ち込んだら走れ!」って言われた。上のページでちょいちょいメッセージが切り替わって、熱血漢なところをアピール。↑これがガッカリなキャプテンの写真(拡大してみるとガッカリ度さらにアップ)。あまりにもガッカリな状況だ...。こんな写真をアップしてたら訴えられるんじゃないかとヒヤヒヤする。前にも書いたかな~、この横浜市の体育協会の広報資料になぜかたけはらさんの写真が載ってるよ!ファンはゲットしときましょう。そんな話はいいとして、今日は負けられないレギュラーシーズン最終戦。負けてもギリギリプレーオフには行けるらしいけど、あまりにもギリギリだと初戦から強豪と対決になって気が滅入るので、今日の試合は何が何でも勝っておきたいところ。言いつつも、最終戦の相手が一番の強豪だったりしないですかね。ファルコンズって...。ワカバヤシ兄弟で出るって空気読めてないゴールド戦士には出場をご遠慮願いたい。朝一8時30分開始の試合だからあわよくば来てくれるなと思ってたけど、ちゃんといた。「S40と木場マーボーズの試合だけは絶対出る」と本人談。君たちはアレだろ、消化試合というか、調整試合だろ。こっちはプレーオフかかってんだ。ケースケは来て無くていなくてホッとした。ところで、前回の試合の感想を宿題にしといたんだけど、その提出がなかなか無くてさ。ミサキ姫に問い詰めたら、今回の試合と合わせて2試合分をまとめて提出すると、自分でハードル上げてきた。