📜 ⬆️ ⬇️

Portable Areas as a modularity option in MVC

One of the first questions I asked myself after becoming acquainted with the basics of MVC3 technology is the way to allocate and reuse functionality in several web projects.
In WPF or WinForms, everything is simple and clear - the isolated functionality is isolated into a module, the module is compiled into a library, the library is connected to the project and reused. You just need to correctly isolate the modules and everything will be fine.

In MVC, if the “isolated functionality” is a set of controllers and views that implement, say, a guest book, they can be isolated as a “region” - area. However, it is impossible to simply take out this area in a separate module - MVC simply will not find your controllers / views in the neighboring libraries.

However, there is a solution, of course, and the well-known MvcContrib library, an open-source project not affiliated by Microsoft, offers it to us.

')
Suppose that you already have a guest book on the site and have a desire to reuse it in another project. What need to do?
  1. Create a project of type ClassLibrary and add references to it on System.Web.Mvc.dll, System.Web.Razor.dll (if the views use Razor), MvcContrib.dll and Microsoft.Web.Mvc.dll (the latter is to support strong typing , you can skip).

  2. Create a project structure that is very similar to a regular MVC template. The only difference is that the Views, Controllers, etc. folders. should be located in the root folder with the name of our allocated area (portable area). In the example, this is the Guestbook. Copy the views and controllers that you want to isolate into this structure.

    All views in the field must be set to the method of compilation - embedded resource (as suggested in the comments, you can also copy the views to the Areas folder of the main project - MVC will find them there)!

  3. Create a registration class that will allow you to associate the main MVC application and the selected area. This class should inherit from PortableAreaRegistration . In the simplest case, it might look like this:
    public class GuestbookRegistration : PortableAreaRegistration { public override string AreaName { get { return "Guestbook"; } } } 

    The only parameter required is the AreaName field with the name of the area.
    However, here you can also change the routes for the selected area:
     public class GuestbookRegistration : PortableAreaRegistration { public override string AreaName { get { return "Guestbook"; } } public override void RegisterArea(AreaRegistrationContext context, IApplicationBus bus) { base.RegisterArea(context, bus); context.MapRoute( "Guestbook_Default", "GuestbookPro/{action}/{id}", new { controller = "Guestbook", action = "Index", id = UrlParameter.Optional }); } } 

    The default route looks, as you might guess, like this: AreaName + "/ {controller} / {action} / {id}". That is, the full path to the index action by default will look like http: // localhost / Guestbook / Guestbook / Index .

The creation of the module is complete :) How to use it? Very simple. We add references to the module and MvcContrib to the main project (well, Microsoft.Web.Mvc is useful :)). Create the Areas folder and copy the Web.config from the Views folder to the Areas folder.


Everything. We start the project and go to localhost / Guestbook / Guestbook (the first guestbook is the name of the area, the second is the name of the controller).

You can also add links to actions from the module and connect them using RenderAction - all as with regular controllers.
 @(Html.ActionLink<GuestbookController>(x => x.Index(), "   ")); @Html.ActionLink("   ", "Index", "Guestbook", new { area = "Guestbook" }, null); @{ Html.RenderAction<GuestbookController>(x => x.Index()); } @{ Html.RenderAction("Index", "Guestbook", new { area = "Guestbook" }); } 

However, in order for strongly typed links to work, the controllers inside the selected area must be identified with the ActionLinkArea ("AreaName") attribute:
 [ActionLinkArea("Guestbook")] public class GuestbookController : Controller { } 


PS Well, the last bonus for those who want to make it work on linux under Mono.
At the moment, you will have to create two Areas folders in the working project structure on the server - with a capital “A” and a small one . The need for “small” is a bug on the part of the MvcContrib library (it carries out preliminary checks). A patch for this bug has been sent to the developers (a one character patch :)).

PPS Surprised that the topic is absolutely not covered in the Habré, and in particular there is nothing particularly in runet.

PPPS In the comments touched upon the topic of applicability of T4MVC for “selected areas”. After a small patch, T4MVC works great. Integration details can be found here.

Source: https://habr.com/ru/post/123819/


All Articles