Archive for the ‘Portable Area’ Category

Portable Area excerpt from MVC2 in Action

If some of you want to know why I have not been blogging as much for the last few months..  and this is why. I have been putting my energy into this book as a co-author.  I am excited to be part of it and glad to share the results of all of this work.

The following is an excerpt from ASP.NET MVC 2 in Action, a book from Manning appearing in bookstores in May.  The early access (MEAP) edition is available now on http://manning.com/palermo2.  Authors include Jeffrey Palermo, Ben Scheirman, Jimmy Bogard, Eric Hexter and Matt Hinze.  Technically edited by Jeremy Skinner.

 

22.1 Understanding the portable area

The portable area is a concept that comes from the MvcContrib project. As the name describes it, it is a native MVC 2 area packaged up in a way that is easier to distribute and consume than an area built with the out of the box MVC 2 support. That is a pretty broad statement so let’s first look at what is in an area and then cover which pieces may need to be made portable.

Areas are a subset of an MVC application that are separated in a way that gives them some physical distance from other groups of functionality in an MVC application. This means that an area will have one or more routes, controllers, actions, views, partial views, master pages and content files, such as CSS, JavaScript, and image files. These are all the pieces that may be used in an area.

Of those individual elements many of them are not part of the binary distribution of a MVC application. Only the routes, controllers, and actions get compiled into an assembly. The rest of the elements are individual files that need to be copied and managed with the other assets that are part of your application. This is reasonably trivial to manage if you build an area for your application and just use it as a way of managing smaller modules of your application. But if you want to use an area as a way for packaging up and sharing/distributing a piece of multi-page user interface functionality, managing all of the individual files make this option a bad choice when integrating someone else’s component with your application.

This is where the MvcContrib project developed the idea of a portable area. By building on top of the existing area functionality, it only takes some minor changes to your area project to make it portable. A portable area is simply an area that can be deployed as a single DLL. The process of making an area portable is pretty trivial. As an area developer, instead of leaving the file assets as content items in your project, you make them embedded resources. An embedded resource is a content file that is compiled into the assembly of a project. The file still exists and it can be programmatically extracted from the assembly at runtime. This means that a portable area only contains a single file, the assembly of the project, rather than all the individual content files.

22.2 A simple portable area

A portable area is a class library project with controllers and views. It has all the trappings of an ASP.NET MVC 2 project: controllers, folders for views and the views themselves. To extract the AccountController we’ll simply move those related files from the default template to a new class library project. The overall structure of the project is the same, but it’s not a web project, as shown in figure 22.1.

clip_image002

Figure 22.1 A portable area class library project

Developers familiar with the ASP.NET MVC 2 default template will recognize most of the files in the portable area shown in figure 22.1. For the most part, it’s exactly the same and in the same structure. The views, however, are not content files like in ASP.NET MVC 2 projects; they are embedded resources. To make a view an embedded resource, highlight it in Solution Explorer and press the F4 key, or right-click it and select Properties from the context menu. The properties window (shown in figure 22.2) will appear.

clip_image004

Figure 22.2 Visual Studio’s file properties window

Select "Embedded Resource" to instruct Visual Studio to include the file as an embedded resource of the project.

Embedded resources

Embedded resources are project artifacts that are compiled into the assembly and they can be programmatically retrieved. Normally, views are set with a build action of "Content" which means they will be stored and accessed like regular files in the file system. Class files have a build action of "Compile", which compiles them into the assembly regularly. For more information on embedded resources, visit the MSDN reference page: http://msdn.microsoft.com/en-us/library/ht9h2dk8.aspx

Like a regular area, portable areas must be registered. Here we use a base class provided by MvcContib, PortableAreaRegistration.

Listing 22.1 Registering our portable area by deriving from PortableAreaRegistration

public class AreaRegistration : PortableAreaRegistration #A

{

public override string AreaName #B

{

get { return "login"; }

}

public override void RegisterArea (AreaRegistrationContext context, IApplicationBus bus) #C

{

context.MapRoute(

"login",

"login/{controller}/{action}",

new { controller = "Account", action = "index" });

base.RegisterTheViewsInTheEmbeddedViewEngine(GetType()); #1

}

}

#A Deriving from PortableAreaRegistration

#B We still provdide AreaName

#C RegisterArea is familiar…

#1 but we call a special method

In listing 22.1 we register our portable area. It’s very similar to the regular AreaRegistration classes we wrote in chapter 21, with one additional, required step: we must call base.RegisterTheViewsInTheEmbeddedViewEngine(GetType()); (#1).

That call allows us to use a special view engine (also included in MvcContrib) that makes our embedded views available to the consuming project. The embedded views are the trick behind portable areas. When our consuming project needs a view, the special embedded view engine can find them. If we didn’t use this view engine, we’d have to automate our deployments so that each portable area’s views were in the correct spot in our projects file system. Even though this can be automated, using embedded views allows us to skip this tedious and error prone step. In the next section we’ll actually use the portable area in our consuming application.

Kick It on DotNetKicks.com

MvcContrib – Portable Area – Visual Studio project template

I just uploaded a visual studio project template for creating portable areas. 

You can find the release here: http://mvccontrib.codeplex.com/releases/view/43162

This project template includes a little msbuild trick to automatically include all of your content files as embedded resources, so you do not have to remember to manually keep track of them.  This was a neat little trick that Steve Michelotti pulled together.

 

Additional information on MvcContrib Portable Areas

As time permits I will put together a walk through using the new project template.  It is really pretty simple if you read through the Portable Area series on my blog.

Kick It on DotNetKicks.com

ASP.Net MVC Portable Area – Part 4 IoC framework support.

Using an Inversion of Control Container is a common scenario that would be needed by a Message Handler.  The Bus has an extensibility point to create the handlers. The model for this should feel similar to the ControllerFactory extension point in the ASP.Net MVC framework.  The sample below shows how to create a Message Handler factory for the StructureMap framework. 

 

image

 

The SetMessageHandlerFactory method should be called once at application startup.   Other than that … this is a pretty simple way to add a Dependency Injection Framework support to the Portable Area infrastructure.

 

This makes it pretty simple for your message handlers to use constructor injection to manage their dependencies.

Kick It on DotNetKicks.com

ASP.Net MVC Portable Areas – Part 3

Using a Portable Area

This is the third part in a series about using a Portable Area (PA) using MvcContrib.  This sample walks through the Host Application side of consuming the Login Portable area.  This example demonstrates how a portable area such as a login can send messages and recieve responses from the host application.  This allows the host application to control the core of the application and lets the Portable Area solve the User Interface portion of the Login.  While this is a pretty simple example it is important to look at the concept of what a Portable Area could solve.  A portable Area could just handling wiring up multiple user interface screens and deal with simple form validation while leaving a lot of from for the host application to control the parts that are important to the application.  Or a Portable Area could provide an entire self contained piece of functionality like a Blog engine, or mulit-instance forum.  There is a large spectrum for how much the Portable Area could provide.  This example focuses on an example where the Portable Area provides the UI and lets the host application own the domain logic.

 

In order to use a Portable Area (PA), the following references need to be added to your MVC project: MvcContrib & the assembly of the Portable Area.

image

 

Wiring up the Portable Area to the application is done at startup.  Portable Areas use the message bus as a way to communicate between the PA and the application. The main method for integrating with a portable area is to register a Message Handler. The sample below demonstrates wiring up a LogAllMessagesObserver, LoginHandler, and a ForgotPassword Handler for the Login Portable Area. 

The call to the InputBuilder.Bootstrap() is required to initialize the Embedded Resource view engine used by this Portable Area infrastructure.

image

Here is an example of an Observer message handler.  This handler simply logs the message to the debugger. This could be used to collect metrics about the system, or log messages to a loggin framework.  The idea of an observer is that it is looking at the base message and not modifying the state of the message.

image

The Login Message Handler receives the login request and than sets the result object which is part of the contract that is specified by the LoginPortableArea from Part 2.

image

In this example the main logic for login is still in a authentication service.  The handler is just used to wire up the message and response of the portable area to the host applications domain services. 

 

Whats Next?

The constructor of the LoginHandler takes an IAuthenticationService as a dependency and my next post will walk through how an Inversion of Control container can be connected to the Bus to allow the framework of your choice to put your pieces together.

 

 

 

Kick It on DotNetKicks.com

ASP.Net MVC Portable Areas – Part 2

Sample Portable Area

This is the second part in a series about creating a Portable Area (PA) using MvcContrib

 

To create a Portable Area, the first step is to create a separate class library project for the Portable Area.  The output assembly is the single file needed to add this functionality to applications which wish to consumer it.

The minimal references required for the Portable Area are shown below:

image

While DataAnnotations is not required to build a PA, using DataAnnotations for Model validation makes distribution of the PA very easy, since the MVC2 DefaultModelBinder supports the DataAnnotations validation out of the box.  If you choose a different validation framework than you would need to distribute those assemblies or possible IL Merge them into your PA.

 The sample PA in the MvcContrib project is a Login Portable Area, this is a pretty simple example, but demonstrates how a PA and application can integrate.  This is also a piece of functionality that most applications need.

 Below is the code listing and structure for the project.  It looks identical to a mulit-project ASP.Net MVC Area.

image

The first difference between creating a Portable Area and a standard area from the files perspective is how the Views are registered with the project. The views Build Action should be changed from content to an Embedded Resource. This allows the views to be embedded into the output assembly so that they view folders and files to not have to be manually copied into each application that uses it.  Instead a special view engine will pull these views out of the assembly at run time and render them the same way that a physical view would be rendered.

image

 

The second item that is needed to create a Portable Area is a specialized registration class for the that inherits from PortableAreaRegistration. This class provides an extended RegisterArea method that sends in the MVC AreaRegistrationContext and a IApplicationBus object to the method.  The IApplicationBus  is the mechanism  that a Portable Area uses to send messages to the hosting application during.  The use of the bus during registration is not required, but it is available in case and specific start up logic is needed to correctly configure the Portable Area.  

The last line of the method show how the Portable Area registers the embedded views with the view engine, using the call to the RegisterTheViewsInTheEmmeddedViewEngine method.

An important caveat around the setup of the Registration class is to make sure that the Registration class is sitting in the same Namespace as the controllers and views.  If the Namespaces do not match the views will not be able to be located.  Since the namespace for the Embedded Resource views cannot be specified declaratively they are created using the Assemblies Default Namespace and the folder structure that they are stored in.  So keeping all of these properties consistent will make everything work.  If you change the default namespace of the project, you will need to update the namespace of your registration and controller classes.

image

The first call in this registration method sends a message to the hosting application.  This is a contrived example but it demonstrates sending a tracing message that can be used by an observer message handler to log the registration activity.  This tracing can be useful since the Portable Areas use the built in MVC registration mechanism for auto discovery and there is not a lot of visibility into the built in registration process. This example shows how a message can be sent between the PA and the hosting application.

image

The LoginController demonstrates the functionality needed to handle displaying the login form and then handling the form post. There are two Actions in the controller, one to render a Login View and a second Action to process the form post and redirect the user on success or , in the case of a login failure, display the login error messages to the user.

image

The message bus is the main mechanism for communicating between a portable area and the hosting application.   This is a very simplistic mechanism that allows the Portable Areas to communicate with the hosting application in a synchronous manner.  

For some scenarios, like when the area should not implement its own database, the host application can own how the domain model is persisted in data storage and the Portable Area can worry about handling the multi-page user interface and other user interface concerns like validating simple data types.

The messages that are passed to the Bus are shown below.

image

The LoginInput represents the data that is collected from the Login screen. It is using the built in  DataAnnotations attributes to handle the simple validation rules.

image

The result object is used to determine if the credentials were valid for the host application and are then used to either display the error message or redirect to a protected page. Since the LoginInputMessage is passed to the bus with a reference, the handlers in the host application can change the Result object’s state and the portable area can than access the Result and determine the correct logic to perform given that result.  The implementation for the handlers will be in the next post in this series.
image

The Index view for the login uses the MvcContrib Input Builders to render a standard form to the page.  The use of the Input Builder allows an host application to override any of the html mark up using the Input Builder partials.  This means that the Portable Area and Input Builders play very nicely with each other.

image

This is what the view looks like in a browser.

image

This is the validation errors that are handled by the Portable Area, using the MVC 2 default model binder.

image

This shows an error message that is passed back from the resulting application. Other rules could be applied as well.

image

 

This is the approach for creating a Portable Area (PA) using the MvcContrib Portable Area feature.  Let me know what you think about this approach, we tried to stay with the simplest approach that could possible work, and focused on making it easy to both develop and consume the Portable Areas.

 

Please leave your comments on what you think of the approach.

Kick It on DotNetKicks.com