Tuesday, January 15, 2013

Data Annotations Extensions

You are probably familiar with the MVC Data Annotations, those attributes that define validations on your model properties.
   1: [MaxLength(20)]

   2: [Required]

   3: public string FirstName { get; set; }

   4:  

   5: [MaxLength(20)]

   6: [Required]

   7: public string LastName { get; set; }

   8:  

   9: [Required]

  10: [Date(ErrorMessage = "You have to be at legal age")]

  11: [DataTypeAttribute(DataType.Date)]

  12: public DateTime BirthDate { get; set; }

  13:  

  14: [Required]

  15: [EnumDataType(typeof(Sex))]

  16: public Sex Sex { get; set; }

  17:  

  18: [Required]

  19: [DataType(DataType.EmailAddress)]

  20: [Display(Name = "Email address")]

  21: public string Email { get; set; }

  22:  

  23: [Phone]

  24: public string Phone { get; set; }

You can define which properties are required, input max length, custom error messages, custom types and built in regular expressions (like email or phone).

However there not enough data annotations in the framework: you can’t define a property that will be only numeric, or credit card number and more. Yes you can define a custom regular expression but who likes to define them?

Let me introduce the “DataAnnotationsExtensions” – an open source library that gives you more attributes like “Digits” or “CraditCard” and more.

Enjoy.

Sunday, January 13, 2013

Query Command Implementation

I’m building a website which has two basic workflows:
- Getting and displaying data from the database.
- Inserting and updating some data.
In other words I have Queries and Commands. I’m not going to talk what is the “query command pattern” - that you can read in Ayende’s “Limit your abstractions” posts. I am going to talk about a nice way to implement that pattern in your MVC application.
Let’s go
The implementation is pretty easy: if you need to query something you create a query class that does it. If you have to insert or update some data then you create a command class. The controller will execute commands and queries directly from it’s actions, no need no create a BL layer, DAL or repository of some kind.
Command
First we need an abstract command class
   1: public abstract class Command

   2: {

   3:     public abstract void Execute(IDocumentSession session);

   4: }

The Command class a single method “Execute” that receives the session as a parameter. The Command class supposed to handle a business logic that creates, updates or deletes something in the application that’s why it has a void as a return type.
Command example


   1: public class RegisterUserCommand :Command

   2: {

   3:     public User User { get; set; }

   4:  

   5:     public RegisterUserCommand(User user)

   6:     {

   7:         User = user;

   8:     }

   9:     

  10:     public override void Execute(IDocumentSession session)

  11:     {

  12:         if (session == null)

  13:             throw new ArgumentNullException("session");

  14:  

  15:         if (User == null)

  16:             throw new InvalidOperationException("Can't register null user");

  17:  

  18:         session.Store(User);

  19:     }

  20: }


When I create the command I pass it my model, throw in some validations and finally use the received session to save the entity. Note that the command should not return a result. It should succeed or fail.
Query
Same as the command first I’ll create an abstract query class a single method:


   1: public abstract class Query<T>

   2: {

   3:     public abstract T Execute(IDocumentSession session);

   4: }


As oppose to the command class, the query has to return a result (T).

Query example


   1: public class CurrentCustomerQuery : Query<Customer>

   2: {

   3:     private string _email;

   4:  

   5:     public CurrentCustomerQuery(string email)

   6:     {

   7:         if (string.IsNullOrWhiteSpace(email))

   8:             throw new ArgumentNullException("email");

   9:  

  10:         _email = email;

  11:     }

  12:  

  13:     public override Customer Execute(IDocumentSession session)

  14:     {

  15:         if (session == null)

  16:             throw new ArgumentNullException("session");

  17:        

  18:         return session.Query<Customer>().SingleOrDefault(x => x.Email == _email);

  19:     }

  20: }

How to use them
So now we know how queries and commands look like, all that’s left is to use them.
The controller is responsible for executing the commands and the queries according to the action scenario.
The easiest way will be creating the command or the query in the controller and simply execute them.


   1: [HttpPost]

   2:  public ActionResult RegisterCustomer(Customer model)

   3:  {

   4:      if (ModelState.IsValid)

   5:      {

   6:          new RegisterCustomerCommand(model).Execute(RavenSession);

   7:          return RedirectToAction("Index", "Home");

   8:      }

   9:  

  10:      return View(model);

  11:  }


However that’s not really testable since we don’t really want to execute our commands or queries. Furthermore it just looks bad.
We need to wrap the commands/queries so that we could mock them easily (and make the code look better).
In order to wrap the queries and the commands we’ll create “CommandExecuter” and “QueryExecuter” with a single method “Execute”.


   1: public class CommandExecuter

   2: {

   3:     public void Execute(Command command, IDocumentSession sesseion)

   4:     {

   5:         command.Execute(sesseion);

   6:     }

   7: }

   8:  

   9: public class QueryExecuter

  10: {

  11:     public T Execute<T>(Query<T> query, IDocumentSession session)

  12:     {

  13:         return query.Execute(session);

  14:     }

  15: }

The base controller will be ctor injected with both of them and will implement two methods “ExecuteCommand” and “ExecuteQuery” which receive a command or a query and call it Execute method.


   1: public class BaseController : Controller

   2:     {

   3:         #region Properties

   4:  

   5:         private QueryExecuter QueryExecuter { get;  set; }

   6:         private CommandExecuter CommandExecuter { get;  set; }

   7:         private IDocumentStore Store { get; set; }

   8:         public IDocumentSession RavenSession { get; protected set; }

   9:  

  10:         #endregion

  11:  

  12:         #region Ctor

  13:  

  14:         public BaseController(IDocumentStore store, CommandExecuter commandExecuter, QueryExecuter queryExecuter)

  15:         {

  16:             Store = store;

  17:             CommandExecuter = commandExecuter;

  18:             QueryExecuter = queryExecuter;

  19:         }

  20:  

  21:         #endregion

  22:  

  23:         #region Executers

  24:  

  25:         protected void ExecuteCommand(Command command)

  26:         {

  27:             CommandExecuter.Execute(command, RavenSession);

  28:         }

  29:  

  30:         protected T ExecuteQuery<T>(Query<T> query)

  31:         {

  32:             return QueryExecuter.Execute(query, RavenSession);

  33:         }

  34:         #endregion

  35:  

  36:         #region Action Execution

  37:  

  38:         protected override void OnActionExecuting(ActionExecutingContext filterContext)

  39:         {

  40:             RavenSession = Store.OpenSession();

  41:         }

  42:  

  43:         protected override void OnActionExecuted(ActionExecutedContext filterContext)

  44:         {

  45:             if (filterContext.IsChildAction)

  46:                 return;

  47:  

  48:             using (RavenSession)

  49:             {

  50:                 if (filterContext.Exception != null)

  51:                     return;

  52:  

  53:                 if (RavenSession != null)

  54:                     RavenSession.SaveChanges();

  55:             }

  56:         }

  57:  

  58:         #endregion

  59:     }



Now when we want to execute a command or a query we’ll call the proper method and pass it the right parameter.


   1: [HttpPost]

   2: public ActionResult RegisterCustomer(Customer model)

   3: {

   4:     if (ModelState.IsValid)

   5:     {

   6:         ExecuteCommand(new RegisterCustomerCommand(model));

   7:         return RedirectToAction("Index", "Home");

   8:     }

   9:     return View(model);

  10: }

Summary
So what we gained?
1. A single command for every action and a single query for every … query.
2. Every command/query has its own logic but they all implement “Execute” method and the base controller just call it from a single place.
3. The deriving controllers are substitutable for their base type and use the BaseController ExecuteCommand or ExecuteQuery.
4. We have two different “Execute” methods, a void one and one which returns a result. Every command/query implements just the one they need and not forced to implement both.
5. Dependency injecting the command and query executers to the controller’s ctor.
Pretty SOLID.