Saturday, December 5, 2009

ASP.NET MVC - Thoughts and advices

It's almost one year ago when I got into web development with ASP.NET MVC. We prototyped with the betas, started using the release candidate to develop a new release of a product early 2009 and switched to final 1.0 when it was released. We went for MVC instead of web forms because we liked the simplicity of the web mvc concept. We also wanted increased testability of our code.

We never regretted our decision. Here are some thoughts, advices, pros and cons about ASP.NET MVC 1.0 after using it on a day by day basis for almost one year:

  • The mvc pattern and the web is really a good duo. I was fascinated when I saw how Rails implemented the pattern with concepts like actions, filters and routes. Fortunately Microsoft didn't reinvent the wheel and implemented most of these proven concepts in ASP.NET MVC.
  • ASP.NET MVC is a presentation layer framework for the web. It's not an application framework like RAILS. There is nothing like ActiveRecord, migrations or test fixtures in the framework. The positive thing is that you can choose whatever technologies you want to add. The negative thing is that you waste time in debates while choosing these technologies.
  • ASP.NET MVC is not a very opinionated piece of software. It provides the hooks to add conventions and functionality, but doesn’t provide much in the way of structure itself. I couldn't find any advices or guidelines from Microsoft. More opinions are available from the guys from CodeBetter or in the Book ASP.NET MVC in Action
  • Model binders and action filters are very helpful to keep controller actions clean. Use these guidelines for deciding when to use them:

  • Consider moving logic to an action filter when you start repeating yourself in your controller code.

    Consider using built in model binding whenever you have to access the requests forms collection in a controller action.

    Consider writing your own model binder if you can't bind your form data with the default model binder.

  • Even thought you can do everything with HTML, CSS and JavaScript the cost of a nice and rich user interface in the browser are not to be sneezed at. In web forms you have a wide range of controls for almost every UI element. In ASP.NET MVC you have to build a lot of UI stuff (at least at time of this writing) by your own. The wonderful JQuery library and it's plugins provide basics like auto complete text boxes, tree views, calendars and popups. But you always have to write your own html helpers to integrate them into your views.
  • The ASP.NET MVC team did a good job and built the framework with testability in mind. Calling controller actions from within a unit test and asserting the action's result is very easy - as long as you don't have real world code in your controller. Even if you do a good job in layering your application the presentation layer is the place where everything is put together. That means that you will mostly end up with many dependencies in your controllers and that's exactly the scenario where unit testing gets hard. Isolation frameworks like Typemock, Moq or Rhinomock can help you overcome these issues. But the use of these tools often lead to over specified tests.
  • Lately we had to extend our product with an outlook addin with a reduced feature set in comparison of the main web client. We decided to implement the web services as RESTful services. ASP.NET MVC 1.0 has no built in RESTful web service support but with a little help from the REST For ASP.NET MVC SDK and the WCF REST Starter Kit it was very easy to build a web API with MVC.
In summary I can say developing web applications with ASP.NET MVC is fun. I'm looking forward for Version 2 which will ship with Visual Studio 2010.

Sunday, January 18, 2009

Layered Architecture with LINQ to SQL (Part 2)

In my last post I mentioned two popular approaches for structuring your data access logic when choosing the domain model: the Active Record and the pure domain model way. In this post I want to explain how I would implement a data access Layer for LINQ to SQL for a pure domain model. There are two reasons why I prefer this to Active Record :
  • I like the idea of persistence ignorance, clean ordinary classes where you focus on the business problem. I'm not too dogmatic about that. As an example I don't care about the LINQ To SQL mapping attributes I have to put in my domain classes.
  • I don't want to run most of my unit tests against the database. The Repository pattern helps a lot in achieving this.
Repositories, Unit Of Work and Entities with LINQ to SQL

The central object of LINQ to SQL is the DataContext object. It tracks changes to all retrieved entities. It implements the Unit of Work and the Identity Map patterns and also provides query functionality on a per table basis. It's similar to NHibernate's Session object. Too bad that Microsoft didn't define an interface for this class (like the NHibernate team did it with the ISession interface). Such an interface is import to provide a stubbed implemenation during unit testing. So let's define our own interface and name it IDataContext:
public interface IDataContext: IDisposable
{
void Commit();

void DeleteOnSubmit<T>(T entity) where T: class;

ChangeSet GetChanges();

IQueryable<T> GetTable<T>() where T: class;

IQueryable<T> GetTable<T>(Expression<Func<T, bool>> predicate) where T: class;

void InsertOnSubmit<T>(T entity) where T: class;
}

The class that implements this interface is just an adapter for the DataContext class. The code is straight forward:
public class LinqToSqlDataContextAdapter: IDataContext
{
private readonly DataContext _dataContext;
private bool _disposed;

public LinqToSqlDataContextAdapter(IDbConnectionConfiguration connectionConfiguration): this(new DataContext(connectionConfiguration.ConnectionString))
{

}

protected LinqToSqlDataContextAdapter(DataContext dataContext)
{
_dataContext = dataContext;
}

public void Commit()
{
_dataContext.SubmitChanges();
}

public void DeleteOnSubmit<T>(T entity) where T: class
{
_dataContext.GetTable<T>().DeleteOnSubmit(entity);
}
//... more adapter code
}

Let's continue with the Repository Pattern. According to Fowler a Repository "provides a layer of abstraction over the mapping layer where query construction code is concentrated", to "minimize duplicate query logic". A Repository usually provides a set of query operations for an Entity. In addition to that objects can be added to and removed from the Repository. My interface for a generic Repository looks like this:
public interface IRepository<T> where T: IGuidIdentityPersistence
{
void Add(T entity);

long Count();

long Count(Expression<Func<T, bool>> predicate);

void Delete(T entity);

bool Exists();

bool Exists(Expression<Func<T, bool>> predicate);

T FindFirst(Expression<Func<T, bool>> predicate);

T Find(object id);

IQueryable<T> FindAll();

IQueryable<T> FindAll(Expression<Func<T, bool>> predicate);
}

I decided to use IQuerable instead of returning a collection as the return value of the FindAll methods. This makes the usage very flexible. IQuerable is a deferred query so clients can add filters as needed. For more specialized methods I think it's better to return a collection than a query.

The generic implementation of IRepository<T> goes here:
public class Repository<T>: IRepository<T> where T: class, IGuidIdentityPersistence
{
private readonly IDataContext _dataContext;

public Repository(IDataContext dataContext)
{
_dataContext = dataContext;
}

public Repository()
{
_dataContext = UnitOfWork.Current;
}

private IDataContext DataContext
{
get { return _dataContext; }
}

public void Add(T entity)
{
DataContext.InsertOnSubmit(entity);
}

public long Count()
{
return DataContext.GetTable<T>().Count();
}

public long Count(Expression<Func<T, bool>> predicate)
{
return DataContext.GetTable(predicate).Count();
}

public void Delete(T entity)
{
DataContext.DeleteOnSubmit(entity);
}

public bool Exists()
{
return DataContext.GetTable<T>().Count() > 0;
}

public bool Exists(Expression<Func<T, bool>> predicate)
{
return DataContext.GetTable(predicate).Count() > 0;
}

public T FindFirst(Expression<Func<T, bool>> predicate)
{
return FindAll(predicate).FirstOrDefault();
}

public T Find(object id)
{
return DataContext.GetTable<T>().Where(e => e.Id.Equals(id)).FirstOrDefault();
}

/// <summary>
/// Returns a query for all object in the table for type T
/// </summary>
public IQueryable<T> FindAll()
{
return DataContext.GetTable<T>();
}

/// <summary>
/// Returns a query for all object in the table for type T that macht the predicate
/// </summary>
public IQueryable<T> FindAll(Expression<Func<T, bool>> predicate)
{
return DataContext.GetTable<T>(predicate);
}
}

I made the class concrete on propose. As the Repository class already defines a lot of helpful methods the class can be used in situations where you don't need a custom Repository. Below is an example where a generic Repository is used in a ASP.NET MVC Controller:
public class BookController: Controller
{
private IRepository<Location> _locationRepository;

public BookController(IRepository<Location> locationRepository)
{
_locationRepository = locationRepository;
}

//...
[AcceptVerbs("Post")]
public ActionResult Edit(Guid id, string title, string author, Guid locationId)
{
Book book = GetBook(id);
UpdateModel(book, new string[] {"Title", "Author"});
Location selectedLocation = _locationRepository.Find(locationId);
book.AddLocation(selectedLocation, GetCurrentUserName());
UnitOfWork.Current.Commit();
return View("Show", book);
}

A custom Repository could look like this:
    public class BookRepository: Repository<Book>, IBookRepository
{
public BookRepository(IDataContext dataContext)
: base(dataContext)
{}

public BookRepository()
{}

public IEnumerable<Book> FindByTitle(string title)
{
return FindAll().Where(b => b.Title.Contains(title)).ToList();
}
}

The implemenation of the Repository pattern I showed in this post adds a layer of abstraction on top of LINQ to SQL and results in a more decoupled architecture. As a side effect the design simplifies database independent testing. The generic Repository provides easy and flexible usage for simpler situations.

Layered Architecture with LINQ to SQL (Part 1)

As with many other Microsoft technologies LINQ to SQL mainly supports a RAD (rapid application development) style of development. You can drag and drop tables into the LINQ to SQL Designer and Visual Studio will define a simple 1:1 mapping, generate domain classes and a typed datacontext for your database. All set, ready to hack! Let's create a win form, drag some controls in it, code some LINQ to SQL queries in a click event handler and bind it to a grid. Sounds easy right? Well it's easy and you can do it, but consider the following problems:
  • Writing database queries in your presentation layer is not as bad as using SQL code in it, but it’s still a questionable practice. If you do it, you’re mixing data access code with business logic and presentation code. This means that you’ve decided to abandon the benefits of the separation of concerns.
  • LINQ to SQL queries are scattered around in your business logic or presentation code. Sooner or later you run into a maintenance problem.
  • There is no concept for code reuse. Queries that need to be used at different places have to be duplicated.
But that doesn't mean that LINQ to SQL is not suitable for building layered enterprise applications. There are a lot of resources available that can help you to structure your data access logic. Most of them are documented in Martin Fowler's Patterns of Enterprise Application Architecture (PEAA) book. If you choose the Domain Model approach there are mainly two options for your DAL:
  • Active Record. Active Record puts data access logic directly in the domain object. In most implementations you can see a set of static finder methods on the domain objects and instance methods for operations like save, update and delete.
  • Pure Domain Model with a Unit Of Work and Repositories. This approach separates the data access logic from the domain objects. With the combination of these patterns different objects exist for different concerns: the unit of work is responsible for change tracking, repositories for data access and domain object for domain logic.
In my next post I want to show you how I would apply the pure Domain Model patterns in the context of LINQ to SQL.