First time here? You are looking at the most recent posts. You may also want to check out older archives or the tag cloud. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS. Thank you for visiting! (hide this)

If your ASP.NET MVC is growing large, it’s likely that you are partitioning your controllers in different namespaces, or maybe even in different assemblies, and it might happen that you have controllers with the same in different namespaces.

Phil Haack and Steve Sanderson wrote some great write-ups on how to partition an ASP.NET application down into Areas, a concept that exists in MonoRail but not in the core ASP.NET MVC framework. The two posts above allow grouping both the controllers and the views, so if you want a complete solution to the aforementioned problem make sure you read them.

What I want to point out here is that both the two approaches above are based on a hidden feature of the framework and the way the ControllerFactory looks for controller class. So it can be used in your own hand-made “area grouping” solution.

Let’s start directly with the solution: if you add to a route a datatoken named “namespaces” with a list of namespaces, the controller factory will look in these namespaces.

Route externalBlogRoute = new Route(
"blog/{controller}/{action}/{id}",
new MvcRouteHandler()
);

externalBlogRoute.DataTokens = new RouteValueDictionary(
new
{
namespaces = new[] { "ExternalAssembly.Controllers" }
});

routes.Add("BlogRoute", externalBlogRoute);

With the MapRoute helper method the things are easier since one of the many overloads allows you to specify directly an array of strings:

routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" },
new[] { "ExternalAssembly.Controllers" }
);

This is easier than having to remember the name of the datatoken key.

The default controller factory already takes into account the namespaces datatoken. In fact it follows this flow:

  1. Look in the namespaces provided inside the route
  2. if not found, then will look into all the namespaces

This is useful if you have many controllers with the same name in different namespaces: by specifying the namespace in the route definition, you are limiting where the framework will look for the controller.

As last point, if the namespace is in an external assembly, you have to add it as reference of the ASP.NET MVC web application project, otherwise it will not probe it.

kick it on DotNetKicks.com

Technorati Tags: ,,
posted on Friday, November 14, 2008 4:05 PM

Comments on this entry:

# re: How to call controllers in external assemblies in an ASP.NET MVC application

Left by Keyvan Nayyeri at 11/14/2008 5:02 PM

Good job, Simo :-)

# re: How to call controllers in external assemblies in an ASP.NET MVC application

Left by Haacked at 11/14/2008 8:24 PM

You can also register more namespaces globally so you don't have to do it per route:

ControllerBuilder.Current.DefaultNamespaces.Add("ExternalAssembly.Controllers");

# re: How to call controllers in external assemblies in an ASP.NET MVC application

Left by Simone at 11/14/2008 8:37 PM

@Phil, thanks for pointing this out.
But then you loose the possibility to call controllers with the same name in different namespaces based on the route:
Forum/Home/List -> Forum.HomeController.List
Blog/Home/List -> Blog.HomeController.List

Comments have been closed on this topic.