Getting Started

First, I would suggest downloading the Source Code and opening up the SampleUCDArchApp (Trunk/SampleUCDArchApp). This application shows how to get started with UCD Architecture and also shows how to use a few features.

Index:

Global.asax

In the global.asax file you have the opportunity to hook up and configure your application for use with ASP.NET MVC and UCDArch. A simple but feature-full global.asax would look like the following

1: public class MvcApplication : System.Web.HttpApplication
2: {
3:    protected void Application_Start()
4:    {
5:        xVal.ActiveRuleProviders.Providers.Add(new ValidatorRulesProvider());
6:
7:        //Register the routes for this site
8:        new RouteConfigurator().RegisterRoutes();
9:
10:        ModelBinders.Binders.DefaultBinder = new UCDArchModelBinder();
11:
12:        InitializeServiceLocator();
13:    }
14:}

Let's step through this one line at a time.

On line 5 we setup xVal, which provides client-side validation. The ValidatorRulesProvider is part of UCDArch.Web and provides a rules provider for NHibernateValidators. If you aren't using NHibernateValidators you can swap in your own library here.

On line 8 we register the routes for this site, which you can do using any method you prefer. Moving the routes into a route configuration class makes them easier to unit test and keep track of. A simple RouteConfigurator class could look like this:

public class RouteConfigurator
{
    public virtual void RegisterRoutes()
    {
        RouteCollection routes = RouteTable.Routes;
        routes.Clear();

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

        MvcRoute.MappUrl("{controller}/{action}/{id}")
            .WithDefaults(new { controller = "Home", action = "Index", id = "" })
            .AddWithName("Default", routes);
    }
}

On line 10 we have ModelBinders.Binders.DefaultBinder = new UCDArchModelBinder();. This sets up our default model binder to be a custom model binder that lives in UCDArch.Web. This binder knows about NHibernate Repositories and can bind complex classes easily. Also if you want to tweak it a little bit, you can inherit from this class and then hook your own implementation up here.

On line 12 we call InitializeServiceLocator(), which hooks up our IoC of choice as the ASP.NET MVC controller factory and also registers some default components. In the future I hope to make some default implementations but for now you can easily roll your own. For example, here is how you would do it with Castle Windsor & MvcContrib.Castle.

private static IWindsorContainer InitializeDependencyLocator()
{
    var container = new WindsorContainer();

    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

    container.RegisterControllers(typeof(HomeController).Assembly);

    ComponentRegistrar.AddComponentsTo(container);

    ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));

    return container;
}


This is all pretty standard except the last two lines (other than the return) need some explanation. ComponentRegistrar.AddComponentsTo(container) is where you can register your components, which will be injected in to your project as desired. A simple ComponentRegistrar would look like this:

public static class ComponentRegistrar
{
    public static void AddComponentsTo(IWindsorContainer container)
    {
        AddRepositoriesTo(container);

        container.AddComponent("validator", typeof (IValidator), typeof (Validator));
        container.AddComponent("dbContext", typeof (IDbContext), typeof (DbContext));
    }

    private static void AddRepositoriesTo(IWindsorContainer container)
    {
        container.AddComponent("repository", typeof (IRepository), typeof (Repository));
        container.AddComponent("genericRepository", typeof (IRepository<>), typeof (Repository<>));
        container.AddComponent("typedRepository", typeof (IRepositoryWithTypedId<,>),
                               typeof (RepositoryWithTypedId<,>));
    }
}

Here I am adding NHibernateValidators as the IValidator implementation, adding in the DB context, and registering the Repositories.

Now also note the line ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container)), which uses Microsoft.Practices.ServiceLocation to register a service locator (and you can create your own if you use something other than Castle Windsor)

First Controller

After adding just those few lines to the Global.asax and setting up your components, you are ready to create a controller. (Note: You may have to configure other settings in the web.config file, like NHibernate settings, as needed)

Let's create an OrderController, which will inherit from SuperController (which is the base controller class in UCDArch). Inheriting from the SuperController gives the following benefits:
  • Easy access to repositories using Repository.OfType<T>()
  • Strong access to the TempData "Message" property using Message
  • Shortcut to the IPrincipal object for the current user through CurrentUser
  • Default Transactions (by default, every action is wrapped in a transaction)
  • Default Anti Forgery Token (by default, every post requires an anti forgery token)

//The following two examples of an OrderController are conceptually the same:

//An example of using dependency injection to get an order repository
public class OrderController : SuperController
{
    private readonly IRepository<Order> _orderRepository;

    public OrderController(IRepository<Order> orderRepository)
    {
        _orderRepository = orderRepository;
    }

    public ActionResult Index()
    {
        IList<Order> orders = _orderRepository.GetAll();

        return View(orders);
    }
}
//An example of using the IRepository property of the SuperController
public class OrderController : SuperController
{
    public ActionResult Index()
    {
        IList<Order> orders = Repository.OfType<Order>().GetAll();

        return View(orders);
    }
}


This was of course just an introduction, please take a look at the SampleUCDArchApp Project in the Source Code for a little more information. I'll be improving that project over time and as new features are added.

Last edited Dec 17, 2009 at 11:11 PM by srkirkland, version 5

Comments

No comments yet.