Previously I wrote an introduction of MVCommand which explained at a high-level what exactly MVCommand was.   I promised to follow up with a post on how to get started, and to list and describe the handful of classes you should implement (or inherit from) to get MVCommand up and running.

Before I go into that, I wanted to give a shout out to Dan Donahue’s great post on building a Hello World app with MVCommand.  I appreciate him taking the effort to try out the framework and also write down his experiences.

And now below are a list of classes to implement (or inherit from) to get started.  Note: this info is also available in the “docs” folder in the repository (located at git@github.com:cerikpete/MVCommand.git).

CommandApplication

Your Global.asax file should inherit from this class.  This is an abstract class that will force you to implement a few methods and properties, listed below.

ServiceLocatorProvider: MVCommand uses the Service Locator pattern to resolve instances of the commands in your application.  Override this property to pass in your own class that implements the ServiceLocatorImplBase class (this class is contained in the MVCommand dll).  Your class should return an instance of your container.  If you do some searching, you should be able to find classes written for your IoC container that can handle all of this (for example, Ayende wrote a WindsorServiceLocator class that allows you to use Windsor with Service Locator).

Example:

protected override ServiceLocatorImplBase ServiceLocatorProvider
{
    get { return new WindsorServiceLocator(IoC.Container); }
}

CommandControllerFactoryType: The framework requires you to provide a factory that creates your front controller (mentioned in detail below). For this property your Global.asax should simply return the type of your factory class.

Example:

protected override Type CommandControllerFactoryType
{
    get { return typeof (MyControllerFactory); }
}

RegisterCommandsWithIoCContainer: This needs to be implemented in order to register your commands with your IoC container.  This should just contain code like you usually would have to register your objects with your container.

RegisterRoutes: This is simply a method where you set up your routes. More details on that below.

Routing in MVCommand

Routing in MVCommand is almost identical to how it works in the ASP.NET MVC framework. The only difference is the naming of the attributes in the routes. Where ASP.NET MVC uses “controller” and “action”, MVCommand uses “context” and “event”. In your RegisterRoutes method in your Global.asax (mentoned above), you should have the following:

routes.MapRoute( "Default", // Route name "{context}.mvc/{event}/{id}", // URL with parameters
new { controller = "Config", action = "DefaultAction", id = "" } // Defaults );

This should handle all of the requests needed by MVCommand, unless you create secure routes (more on that in another post).

One thing you’ll note is that the controller and action property still exist in the default route.   The controller value should point to the front controller class for your app (described below in “The Front Controller”).  This is needed because we still need to default to your front controller in order to then correctly resolve the commands later on in the request pipeline.

The Controller Factory

The controller factory is needed in order to pass your front controller instance to the MVCommand framework (mentioned in more detail below). To implement this, simply create a class that inherits from CommandControllerFactory. It will have to implement one method, CreateController, which will simply return an instance of your front controller (more on that below).

Example:

public override IController CreateController(RequestContext requestContext, string controllerName)
{
    var controller = new MyController();
    return controller;
}

The Front Controller

The front controller will act as a gateway between your app and the framework. It sets some properties so that the front controller in the framework can correctly react to any commands fired in your app.

To create one, simply create a class and have it inherit from CommandController. Two properties will need to be implemented:

CommandTypes: This simply returns all types in the assembly that contains your commands.

BindableCommandType: This returns the type you created in your app that implements the IBindableCommand<ModelType> interface (mentioned in more detail below).

Here’s an example of what your front controller class might look like:

public class MyController : CommandController
{
    public override Type[] CommandTypes
    {
        get { return typeof (MyCommandClass).Assembly.GetTypes(); }
    }
    public override Type BindableCommandType {
        get { return typeof (BindableCommand<>); }
    }
}

BindableCommand and Validation Objects

In the framework there is the concept of a BindableCommand, which is any command that implements the IBindableCommand<ModelType> interface. This tells the framework that you have a command that needs data loaded from the view (for example, form values). Behind the scenes, the framework will load data from the view to whatever you passed in to the ModelType generic property.

To do this, create a class that implements the IBindableCommand<ModelType> interface. This is the class that your commands will inherit from if they require view data. This class will need to implement two methods, one for when the result of the command is a success, and one if an error occurs.

You will note that these methods return ISuccess and IErrror, respectively. The MVCommand framework provides a default implementation of ISucess (a class named Success) that you can use, however there is no default implementation of IError (since typically it will depend on the type of validation you use), so you will have to create a class that implements the IError interface.

Once those classes are created, you can implement your BindableCommand class to return the appropriate data.

View Base Classes

The pages and user controls in your app will need to inherit from one of the base view classes provided by the framework. These are similar to the classes provided by the ASP.NET MVC framework, but their functionality is a bit different. Behind the scenes, the MVCommand base classes check the ViewData dictionary for the model passed in to the generic property of the base class. The provided classes are listed below:

ViewBasePage<ModelType>: Useful for aspx pages, gives the page access to the object in the ViewData dictionary of type ModelType

ViewBaseControl<ModelType>: Works like the ViewBasePage<ModelType> class, but used on controls (ascx) instead of pages

NullableModelControl<ModelType>: Useful for controls that have a model that might not exist in the ViewData dictionary (ex: if a control is used both to create a new object and edit an existing object, and when creating a new object nothing will be present in the ViewData dictionary)

ViewResultControl: Useful as a base class for controls whose purpose is to see if an IError or ISuccess object is present in the ViewData dictionary. It has two properties on it: ErrorResult and SuccessResult, which return IError and ISuccess, respectively.

Utility Classes

There are many classes in the framework that help with other functions, such as generating a url for a specific command, as well as for redirecting to a specific page once a command is complete.  Those are out of the scope of this post, but are documented in the file in the docs folder, mentioned at the beginning of this post.

What’s Next

That’s it as far as classes you need to implement.  With this info you should be able to get started with an MVCommand app.  In future posts I want to show examples of a simple command that uses model binding (that inherits from BindableCommand<ModelType>).