Philさんすげーよ。あんたやっぱり最高だよ。
RCに対応させたAreasのコードがアップロードされてる。
Grouping Controllers with ASP.NET MVC
RouteCollectionの簡単登録ヘルパーと、Viewの位置を解決させるためだけのカスタムViewEngine。
何でこれだけで出来るのか不思議だ。コントローラのパスだってデフォルトの名前空間だって違うのに、ControllerFactoryを作ることなく出来るんだよ。
で、いつだったか忘れた(ベータだっけな~?もっと前?)けど、ルーティングのDataTokensにNamespacesを入れとけば、コントローラのNamespaceに自動で入れてくれるっていう仕様になったような。
気になったらとめられない。とりあえずRCのソースをチェック。
たぶんControllerFactoryあたりだろう。
protected internal virtual Type GetControllerType(string controllerName) {
if (String.IsNullOrEmpty(controllerName)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
}// first search in the current route's namespace collection
object routeNamespacesObj;
Type match;
if (RequestContext != null && RequestContext.RouteData.DataTokens.TryGetValue("Namespaces", out routeNamespacesObj)) {
IEnumerable<string> routeNamespaces = routeNamespacesObj as IEnumerable<string>;
if (routeNamespaces != null) {
HashSet<string> nsHash = new HashSet<string>(routeNamespaces, StringComparer.OrdinalIgnoreCase);
match = GetControllerTypeWithinNamespaces(controllerName, nsHash);
if (match != null) {
return match;
}
}
}
正解だね。
太字のところ。コレでRouteData.DataTokensからNamespacesを取得して、Controllerの型を判定してる。
public static class AreaRouteHelper {
public static void MapAreas(this RouteCollection routes, string url, string rootNamespace, string[] areas) {
Array.ForEach(areas, area => {
Route route = new Route("{area}/" + url, new MvcRouteHandler());
route.Constraints = new RouteValueDictionary(new { area });
string areaNamespace = rootNamespace + ".Areas." + area + ".Controllers";
route.DataTokens = new RouteValueDictionary(new { namespaces = new string[] { areaNamespace } });
route.Defaults = new RouteValueDictionary(new { action = "Index", controller = "Home", id = "" });
routes.Add(route);
});
}public static void MapRootArea(this RouteCollection routes, string url, string rootNamespace, object defaults) {
Route route = new Route(url, new MvcRouteHandler());
route.DataTokens = new RouteValueDictionary(new { namespaces = new string[] { rootNamespace + ".Controllers" } });
route.Defaults = new RouteValueDictionary(new { area="root", action = "Index", controller = "Home", id = "" });
routes.Add(route);
}
}
なので、上記ヘルパー(Philさんのコードです)の太字の部分さえ書いておけば、ちゃんとサブフォルダーのControllerとしてインスタンスを作ってくれる。凄いな~。
Namespacesがうんたらかんたらってアナウンスしてたときは、はぁ、そうですか、それ何に使うんですか?ってなもんだったけど、こうやって実装を見せられると納得。
ところで、Windows Live Writerのアドインでコードを色つきに出来るみたいだけど、BloggerにポストするとCSSがエンコードされちゃってちゃんと出来ない。使い方としてはCSSを外部に出してlinkタグを書くのが正んでしょうか?その場合、外部CSSはどこに置いておくのが正しいんでしょうか?いまいち使い方が分からずだけど、徐々に慣れていこうと思うところです。