ASP.NET MVC – Defining an application architecture

Introduction

ASP.NET MVC is creating some buzz at the moment and has been long awaited. Being a Microsoft product, MVC will be launched into the mainstream development arena and like webforms, could and hopefully will be a popular web development platform that will be around for years to come . Microsoft and some of the key players in this technology and has already got a good community going. The official ASP.NET MVC site contains some very light and quick code tutorials to illustrate the features of MVC.

Although this is all good, I do have some concerns. It starts with what developers learn, the tutorials on the official asp.net mvc site are aimed at developers at different levels and are for illustration only. They are not samples of production quality code. What is missing at the moment are the better practice and guidelines for developing line of business application which I am sure 99% of applications developed with ASP.NET MVC are going to be for.

Separating concerns

On the official ASP.NET MVC site, you will find code examples that are directly fetching data using linq for entities with linq queries directly in the controllers. Its not the responsibility of the controller to fetch data in this manor, their is at least a layer or two missing between controller and data access. My concern is that we will end up with same situation that is present in webforms where applications could be developed with most of the application logic ending up in the controllers (like code behind in webforms).  ASP.NET MVC already is enforcing the separation of concerns for the view but not the controller and model. This is where the design focus is needed.

Layers and tiers

Layering software is probably one of the most basic concepts in the software development that I think is under estimated. I have seen on various projects in the past that its easy to get wrong with either too few or to many layers. I find that logical layers can be defined by separating out the concerns at a high level.

A layer is a logical grouping of code that have a common concern. A tier is typically a physical boundary like a server or client PC. A tier will contain at least one or more layers. Layers that are designed to run in the same tier typically communicate in a finely grained manor (chatty interface) where commutating across tiers should be coarse grain (chunky interface). 

You must either be new to software development have lived in a cave or something if you have not heard of n-tier architecture.  I mention tiers here because i one of the principles that is usually forgotten about in that, when communicating across tiers, do so in a coarse grain mannor.

High above the ground

The architecture that I am defining is nothing new, its a very common scenario using some Domain Driven Design concepts. An alternative variant of this architecture is an SOA implementation. The SOA variant would be the right choice an enterprise level application. The simpler variant of this architecture can be migrated to the SOA variant.

Conceptual logical layers (simple variant)

conceptual logically layers

UI tier – This is the end users computer which will access your application via an internet browser. So the user interface layer will contain (x)html and CSS. Plus this layer could contain JavaScript, silverlight, Flex etc.

Presentation tier – In this tier, you have two layers, the controller and presentation processes. The controller layer will be invoked by the ASP.NET MVC framework in response to an http request. Your controller should do nothing more than delegate any processing to logic in the Presentation Processes layer. The Presentation Processes layer will typically request information from the service layer and process the service response by mapping the information to an object that both Presentation Processes and the controller layer know about. One of the benefits that this gives, is that you could develop your application that is decoupled from the service layer.

Business tier – This tier is very flexible in its implementation. In its most simplest form, it could be run in process on web server that will actually remove the physically boundary between the business and presentation tiers. For enterprise level implementations, this tier could be made up my many separate applications that could be distributed across many application servers. Regardless of the physically boundary, the Server layer should be thin as logic goes. The service layer provides an API to consumers. Beneath the service layer you have the domain layer that contains the business logic and represents the business model. The repository layer is bridge between your application logic and data persistence.

Persistence tier – Does what it says on the tin, this would typically be your database server(s). 

SOA variant

 

Here is the conceptual logically layers using an SOA approach.

image

The key difference here is that the service layer is broken up into multiple services that provide a distinct function. SOA is a massive subject that i would not do it any justice trying to sell it, but using this approach gives you many benefits that the development investment is worth it.  If you are have your business tier running out of process or on different services then WCF is the right technology for the job.

Although I have used ASP.NET MVC in the title of this post, this architecture is relevant for most technology implementations. Everything below the controller layer is plain .net code that you could put any .net view technology at the top of this architecture.

Architectural Rules

Rules are needed for any architecture, these are the common rules that I like to stick to.

  • A layer can only see what is beneath it, never above it.
  • A layer must only see the layer directly below it and not the layers further down the layer stack.
  • Use message objects to communicate between layers that are across tiers (although, using message objects between any layer is also good).
  • Limit your cross cutting concerns. (logging and security are typical candidates as a cross cutting concern. Loads of utilities classes/assemblies are not).
  • Strive for low coupling – By enforcing a layer policy where you can only see the direct below helps here. Using interfaces that your concrete classes implement gives you a recipe of low coupling as with so many other benefits.
  • No leaky abstractions.

Next steps

At this point while writing this post, i started to create an ASP.NET MVC application using this architecture. This post was starting to get to big so i have split it up. Here is the next post to continue on this topic.

Implementing the Repository and Finder patterns

Introduction

Over the last year I have been developing my own application using Domain Driven Design (DDD). I am also working on products in my day job that uses DDD. In the last month, myself and my fellow developers that I work with, went on a little journey to find the right way to implement the repository pattern including queries. My fellow devs and I wanted a solution to achieve the following goals:

  • A solid OO approach that was not bound to a specific technology. Meaning that we could develop this in C# or Java or what ever language.
  • No leaky abstraction. For example, we are using nHibernate at the moment, but in the future we might choose to use a different Object Relational Mapper (ORM). We don’t want our Repository or Finder interface to expose Nhibernate interfaces like “ISession” or “ICriteria”.
  • A repository per aggregate root.
  • No code duplication
  • Fully testable, driven out by our unit tests and me able to mock out the dependancies.
  • Friendly to our Inversion of Control (IoC) framework (ninject, spring.net and castle Windsor etc)
  • Provide a fluent interface to our repositories.

None of us are new to the Repository pattern or ways to implement query objects, so we all have ideas and existing code for tackling this. Combined we come up with this.

In my own application, my implementation used extension methods, its worked well, but because extension methods are static, i had no way of mocking them out  with Rhino mocks. This was not a showstopper, but meant that when i was writing unit tests in my service layer for example i have to set up the data to satisfy the logic in the extension methods.

Throughout the rest of this post, i will be using code from my own application.

The desired result


Here is an example of how we intent to use our repositories:


ApplicationUser user = applicationUserRepository
    .Find.ByLoginName(request.LoginName);

As you can see the repository has a find property on it that exposes a  ByLoginName method that takes a string argument and returns a single ApplicationUser object.

Entity Implementation


The ApplicationUser is a Entity, all of my Entities inherit from a base class called EntityBase:

public abstract class EntityBase
{
    private int id; 

    protected EntityBase() : this(0) { } 

    protected EntityBase(int id)
    {
        this.id = id;
    } 

    public int Id
    {
        get { return this.id; }
    } 

    public abstract bool IsValid();

    ...
}

Not much to it this, all my entities have an identity and i want all my entities to be able to state if the data they contain is valid

Repository Implementation

All of my repositories extend a base IRepository interface.

public interface IRepository<T> where T : EntityBase
{
    T Get(int id);
    void Save(T entity);
}

As you can see the generic type is constrained by the EntityBase type. The IRepository interface is not used directly outside of my repository layer, but is extended by the typed Repository interfaces:

public interface IApplicationUserRepository : IRepository<ApplicationUser>
{
    IApplicationUserFinder Find { get; }
}

In my application, I use dependency injection so my repositories are injected using the typed interface.  IApplicationUserRepository has one member being the Finder interface (more on that below).

One of my objectives was to remove duplicate code, in my effort to do this, i have an abstract class in which all my repositories inherit from.

public abstract class EntityRepository<T> : IRepository<T> where T : EntityBase
{
    protected readonly IPersistanceRepository repository;

    public EntityRepository(IPersistanceRepository repository)
    {
       this.repository = repository;
    }     

    public virtual T Get(int id)
    {
       return repository.Get<T>(id);
    } 

    public virtual void Save(T entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        } 

        if (entity.IsValid())
        {
             repository.Save(entity);
        }
    } 

     protected IQueryable<T> Query()
     {
         return repository.Query<T>();
     }

 }

This class must be supplied an instance of IPersistanceRepository.  Here is the IPersistanceRepository interface

public interface IPersistanceRepository
{
    T Get<T>(int id);
    void Save<T>(T entity);
    IQueryable<T> Query<T>();
}

A concrete implementation of the  IPersistanceRepository interface is the technology / ORM specific stuff. I am using NHibernate 2.0, so my concrete implementation is called “NHibernateRepository”. By using the IPersistanceRepository interface i am keeping the specifics abstracted away inside the concrete class. I have been able to successfully swap my IPersistanceRepository instance from NHibernate to a DB4o implementation with ease and no effect to my repositories.

Finder Implementation

Like the IRepository interface is used as a base interface, i also have a base IEntityFinder interface which again is not directly used outside of my repository layer.

public interface IEntityFinder<T> where T : EntityBase
{
    IQueryable<T> DataSource { set; }
}

As you can see, the interface has a DataSource property of IQueryable, the reason for this is that I am using System.Linq in my project which I will come onto later. But its purpose is to give the Finder a datasource. Now for the IApplicationUserFinder interface.

public interface IApplicationUserFinder : IEntityFinder<ApplicationUser>
{
    ApplicationUser ByLoginName(string loginName);

    ApplicationUser ByToken(Guid token);
}

The typed Repository

Now for my implementation of my typed Repository.

public class ApplicationUserRepository : EntityRepository<ApplicationUser>, IApplicationUserRepository
{
    private readonly IApplicationUserFinder finder; 

    public ApplicationUserRepository(IPersistanceRepository repository, IApplicationUserFinder finder)
        : base(repository)
    {
        this.finder = finder; 

        this.finder.DataSource = Query();
    } 

    public IApplicationUserFinder Find
    {
        get { return finder; }
    }
}

This repository derives from EntityRepository and implements IApplicationUserRepository. Its constucted with its dependencies being injected. The Finder instance has it datasource set to IQuerable<ApplicationUser>.

The typed finder

using System.Collections.Generic;
using System.Linq;

public class ApplicationUserFinder : IApplicationUserFinder
{
    private IQueryable<ApplicationUser> users; 

    public IQueryable<ApplicationUser> DataSource
    {
        set { users = value; }
    } 

    public ApplicationUser ByLoginName(string loginName)
    {
        if (string.IsNullOrEmpty(loginName))
        {
            throw new ArgumentNullException("loginName");
        } 

        return users.Where(u => u.LoginName == loginName).FirstOrDefault();
    } 

    public ApplicationUser ByToken(Guid token)
    {
        return users.Where(u => u.Token == token).FirstOrDefault();
    }
}

What do we have then

We have our entity, repository and Finder created. The repository and Finder have typed interfaces, which means i can wire these up in my IoC container. My IEntityFinder interface sort of went against my goal of no leaky abstraction as its using System.Linq, but i think i can live with myself. By having my finder implement an interface i could have different concrete implementations.

My finder is returning a single instance of ApplicationUser. I could have finder methods that return Iquerable that allows for method chaining etc. Plus i have not allowed for “And”, “Or” or “Not” as that is a different topic. But i have a base to work on.

nibernate repository

To be more code complete here is a snippet of my NHibernate repository that returns the initial query. I am using nhibernate 2.0 with nhibernate.linq.

    using System.Linq;
    using NHibernate;
    using NHibernate.Linq;

    public class NHibernateRepository  : IPersistanceRepository
    {
        private readonly ISessionLocator sessionLocator;

        public NHibernateRepository(ISessionLocator sessionLocator)
        {
            this.sessionLocator = sessionLocator;
        }

        public T Get<T>(int id)
        {
            ISession session = sessionLocator.ActiveSession();

            return session.Get(id);
        }

        public void Save<T>(T entity)
        {
             ...
        }

        public IQueryable<T> Query<T>()
        {
            var qry = from t in sessionLocator.ActiveSession().Linq()
                      select t;

            return qry.AsQueryable();
        }
    }

The beauty of this that the NHibernate specific code is in one place, my repositories and finders have no knowledge of nhibernate. In my finders, i am using linq for objects and lambda’s for my logic. Because i am using IQuerable, i can build up the query through my finders and the execution is deferred until i call a method like “ToList” or “First” etc. The queryProvider in nhibernate.linq builds the sql statement and hits the database once with the specific query.

Finally a big thank you to Neil Martin and Tim Escott for their involvement on this. Please read this post “Creating Fluent finders and repositories part 1 which continues from this post.