Wednesday, February 29, 2012

ASP.NET MVC - Pluggable application modules/components/area/features

This article discuss about how to develop ASP.NET MVC application which has loosely coupled modules (or features) which can be developed separately without any directly dependency and those modules can be plugged-in to main application without any extra bit of code.

Business Value:
This is specifically useful for product development. Using this approach, each module can be developed separately and deployed/shipped with product separately. This helps in building different version of product like: Basic, professional, premium and enterprise. This loosely coupled feature approach enables to either build separate installer with required features as per different versions or master setup which can install only defined features as per license key used during installation.




Building application:
Below step by step process demonstrates how to build application with pluggable modules/areas in ASP.NET MVC 3.
Suppose we want to build a product which has following modules:
1.      Marketing
2.      Sales
3.      Billing
4.      Inventory
5.      Warehouse
And we want to build a product which allows selling/distribution/deployment of each above modules as separate feature. Typically such products will have some basic features/infrastructure and these modules will fit on top of that. So let’s assume we have basic application with master page, landing page, authentication, security, logging and related resources. We will build application with pluggable modules/component/features for above modules.

Open visual studio and create empty ASP.NET MVC 3 project. Select empty template from below step. (I have named Project/solution as ProductDemo in this example).

You will see empty project in solution explorer like blow:
Now click on Controller to add HomeController, select Empty controller for Template.

Create index view for HomeController to provide landing page of application.

Pluggable modules menu items and expected output:
_Layout.cshtml (Views\Shared folder) is configured to create menus pointing to each above expected modules.

With this, output of application now looks like below:








Creating Areas folder structure and get sample of XXXXAreaRegistration file:
Now click on Project and select Add->Area from context menu. This step will create basic folder structure for Area framework. Specify Marketing as Area name and complete step. This will now create Areas folder and folder structure for Marketing with XXXXAreaRegistration.cs file.
Now take a backup of MarketingAreaRegistration.cs file since we are going to delete Marketing folder in next step. This file will be useful when we will add Marketing module in solution as separate project. (This file can also be created manually once structure is understood).
Now remove Marketing folder.
Adding Pluggable module/area to ASP.NET MVC Project:
Now we are about to start project of added new pluggable module for ‘Marketing’. Right click on solution and choose option to add new project. In below dialog box do following:
·        Select ASP.NET MVC 3 Application
·        Name project as ‘Marketing’
·        Set Location as …\ProductDemo\Area
New project should be created in Areas folder we created in just few seconds before. Create project with empty template.
From newly created “Marketing” project, remove Content folder, scripts folder, view/shared folder and global.ascx file. These are added as part of full MVC project but not needed for us since we are creating this as pluggable module/area.  After this step, solution should look like following:
Since we saved new project marketing under Area folder, it is appearing as hidden folder in ProductDemo/Area folder in solution explorer. DO NOT include this folder in project.
Add MarketingAreaRegistration.cs file at project root in marketing project and change its namespace to match with project name spaces, like below:














Now set output directory of Marketing project to ..\..\bin\ so that compiled dlls are placed in bin directory of ProductDemo (Main application) application.
In marketing project, modify web.config file to remove connection strings, authentication, membership, rolemanager, profile etc sections.

Now create controller Marketing (You can have any other controller as well) in Marketing project. Create index view and place content “Welcome to Marketing Module” like below:


Now application is ready with marketing module. Compile the solution to build all projects in solution. After compilation take a look at ProductDemo\bin folder and you will see compiled dlls like below:


Now run application to see its working. Click Home and Marketing links to see how application is switching between main application shell and marketing module.


Repeat all steps of “Adding Pluggable module/area to ASP.NET MVC Project” section to define rest all modules.


How this works?

ASP.NET MVC Areas structure enables creating separate logical modules and those still resides in same project and binary. Notice xxxAreaRegistration.cs in marketing (or any new project added as per this process) which is inherited from AreaRegistration. This file tells two things to ASP.NET MVC and Routing framework: 1) Area name and Rout for accessing Area and its controller actions.

Global.ascx.cs in Main application (ProductDemo) has following code block. This block registers all areas defined in all assembly present in application bin directory. Remember we have directed output of marketing module to main application bin directory.

Application Master Page - main application has master page (_Layout.cshtml) which is at parent directory in ASP.NET application. As per ASP.NET framework, this layout is inherited to its all sub directories. This way even if marketing is separate project it inherits master page of main application and same applies to all other resources like CSS, image, javascripts and other static resources/pages.


What more can be done?
·        Menus to access such modules can be built dynamically by looking at directories/module directory under Areas folder. If area present in folder, construct menu for its pages and show it on application.
·        Consume WCF service in application. WCF services which are common among main application and module/area project, those needs to be referenced in both the project. Any service which is only required for module, should only be referenced in module.
·        CSS and images can be divvied in such a way that all common resources reside in main application content folder and referenced in _Layout.cshtml. CSS, image and other resources which are specific to module can be placed in module. One more layout page can be introduced at module level which is inherited from main application layout page.
·        Create installer (setup) to package such pluggable modules and install them on web server under IIS. Refer Installer - ASP.NET MVC - Pluggable application modules/components/area/features

Source Code: Download Project