Simone Chiaretta is a Software Architect and Developer from Milano, Italy that enjoys sharing via his blog his development experiences and more than decennial knowledge on web development with ASP.NET and other web technologies. He is Microsoft MVP in ASP.NET and he has been involved in many Open Source projects, but now he focuses only on SubText and taking it to the next level. He just wrote a book: Beginning ASP.NET MVC, published by Wrox Simone is a DZone MVB and is not an employee of DZone and has posted 67 posts at DZone. You can read more from them at their website. View Full User Profile

How to Call Controllers in External Assemblies in an ASP.NET MVC Application

12.25.2008
| 11187 views |
  • submit to reddit

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.

 

References
Published at DZone with permission of Simone Chiaretta, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)