Sunday, 31 August 2014

A CQRS Implementation with ASP.Net MVC and Entity Framework

Previous posts in this series

Considering a CQRS approach with ASP.Net MVC

Even a quick read of the various blog posts and other web based information on using CQRS with .Net reveals it can mean a lot of things to different people. To my understanding, at scale, it's a recognition that your read and write operations are likely to require quite different approaches. Reads for example may be coming from denormalised or cached information, and writes might go to queues for subsequent processing. Which is all a bit removed from a more basic CRUD approach where we simple read and write to the database.

In truth though, I didn't need - at least yet - these type of performance improvements. Nonetheless, there remains value for me even in a smaller-scale application in handling query and command operations more distinctly. Which really means in practice that rather than having a service and/or repository layer that provides methods such as GetCustomers, GetCustomerById, SaveCustomer, DeleteCustomer etc. we instead have discrete classes that handle each of these query or command operations. It means more classes for sure, but each one being smaller, more focussed and adhering much more closely to the single responsibility principle.

Another advantage of this approach I find is a better aligning the language of the application or code that of the logic we are looking to model - the ubiquitous language between the developers and the business. One example I had was having user's sign up for a particular event. With the CRUD approach I would likely have created something like an EventUser class - containing references to the Event, the User and some supplementary information such as the date of sign up. And then have a method in my service layer for SaveEventUser().

None of this is really language a business stakeholder would talk - in contrast the creation of a SignUpUserForEvent command does align much more closely.

Finally with this approach I hoped to avoid some issues I've found in the past with a more loose approach to dealing with the Entity Framework context. With this method, we would simply create the context within the query or command object, carry out the read or write operation, save changes and allow the context to go out of scope. With that tighter control there's less room for bugs or unexpected side-effects.

Scenarios

The method I've set up - closely following the example provided by Adam Tibi in his blog post on implementing a CQRS-based architecture with MVC - contains the following, inter-related components:

  • Each controller with functions that require reads (all of them) or writes (some of them) contain dependency injected instances of QueryDispatcher and CommandDispatcher
  • The QueryDispatcher takes type parameters for a query result (or view model) that implements IQueryResult, and a query that implements IQuery. Based on that, using Ninject, the appropriate IQueryHandler is found and executed, passing the query and returning the result.
  • Within the handler, we instantiate the EF context and carry out the appropriate querying and mapping operations to construct the result.
  • Similarly the CommandDispatcher takes a type parameter for the command and the appropriate ICommandHandler is found and executed.
  • Within the handler, we instantiate the EF context and carry outs the appropriate write operation.
  • Command handlers return a simple and standard CommandResult with a status flag, any error messaging and an data object used in cases such as where we need to know the Id of the entity just created.

Given that, we have the following three types of data flow through the application.

Reads

The following diagram illustrates the components involved in handling a read (or query) operation, most usually in the preparation of a view model for presentation of information in a view:

The data flow through these components is as follows:

  • Controller action method takes a parameter of type IQuery. This might be as simple as an Id for the record to display, or something more complex like a set of search parameters.
  • The controller action calls the query dispatcher, passing the query along with the type parameters for the query and the view model (which implements IQueryResult).
  • The appropriate IQueryHandler is called, which uses the EF context to get the data specified by the query and AutoMapper to map or project it into the view model.
  • The view model is passed to the strongly typed view.
Writes

A similar pattern but involving different components handles a write (or command) operation, processing updates that come direct from a form post, an example being the sign-up of a user for an event which comes from a form posting the Id of the event:

Again, to further describe this process:

  • Controller action method takes a parameter of type ICommand that is constructed via MVC model binding from the form post.
  • Further parameters as appropriate are added to the command object (e.g. the Id of the logged in user).
  • The controller action calls the command dispatcher, passing the command along with the type parameter for the command.
  • The appropriate ICommandHanlder is called, which uses the EF context to carry out some validation and make the appropriate model updates.
  • A standard CommandResult object is returned containing a success flag, any error messages and where useful, any response data (such as the Id of the newly created record).
Validated Writes

A complication arises when we come to consider validation. Normally with ASP.Net MVC we'll handle this with data annotations on our view model, which tie in nicely with the framework to provide both server and client side validation. I don't want to lose that facility by say moving the validation up to the command handler. But equally, it doesn't seem right to be passing the view model itself as the command object - the former being clearly part of the presentation layer, not something for data processing.

The way I handle this is to post the view model and handle validation as per usual MVC model binding and validation patterns. If validation passes, I map the view model to a command object, and then continue as per the "Writes" example above.

]

Once more to flesh this diagram out a bit.

  • The presentation of the form data on first load is handled as per "Reads" above.
  • The form post controller action method takes an instance of the view model that is constructed via MVC model binding from the form post/
  • Validation is carried out both client and server side using standard MVC techniques with ModelState.
  • If validation failed, the view model is repopulated with any supplementary information that hasn't been passed in the form post (e.g. the options in selection lists) and returned to the view.
  • If validation passes the view model is mapped (using AutoMapper) to a command object that implements ICommand.
  • From here on we proceed as per "Writes" above.

An end-to-end code example

This example presents the various code excepts that implement this pattern, for the example of a simple process to present a form for editing, validate the submission and process the update.

Set-up

The first step is to create the necessary components for the actual query and command handling - this includes the handler itself, but also various marker interfaces that will be used in the process of matching the appropriate handler from a given query or command.

Firstly for queries:


    // Marker interface to signify a query - all queries will implement this
    public interface IQuery
    {        
    }
 
    // Marker interface to signify a query result - all view models will implement this 
    public interface IQueryResult
    {
    } 
 
    // Interface for query handlers - has two type parameters for the query and the query result
    public interface IQueryHandler<TParameter, TResult> 
       where TResult : IQueryResult
       where TParameter : IQuery
    {
        Task<TResult> Retrieve(TParameter query);
    } 

    // Interface for the query dispatcher itself
    public interface IQueryDispatcher
    {   
        Task<TResult> Dispatch<TParameter, TResult>(TParameter query)
            where TParameter : IQuery
            where TResult : IQueryResult;
    }
 
    // Implementation of the query dispatcher - selects and executes the appropriate query
    public class QueryDispatcher : IQueryDispatcher
    {
        private readonly IKernel _kernel;

        public QueryDispatcher(IKernel kernel)
        {
            if (kernel == null)
            {
                throw new ArgumentNullException("kernel");
            }

            _kernel = kernel;
        }

        public async Task<TResult> Dispatch<TParameter, TResult>(TParameter query)
            where TParameter : IQuery
            where TResult : IQueryResult
        {
            // Find the appropriate handler to call from those registered with Ninject based on the type parameters
            var handler = _kernel.Get<IQueryHandler<TParameter, TResult>>();
            return await handler.Retrieve(query);
        }
    } 

And similarly for commands:


    // Marker interface to signify a command - all command will implement this
    public interface ICommand
    {        
    }
 
    // Interface for command handlers - has a type parameters for the command
    public interface ICommandHandler<in TParameter> where TParameter : ICommand
    {
        Task<CommandResult> Execute(TParameter command);
    } 
 
    // Simple result class for command handlers to return 
    public class CommandResult
    {
        public bool Success { get; set; }

        public string Message { get; set; }

        public object Data { get; set; }
    } 
 
    // Interface for the command dispatcher itself
    public interface ICommandDispatcher
    {
        Task<CommandResult> Dispatch<TParameter>(TParameter command) where TParameter : ICommand;
    } 
 
    // Implementation of the command dispatcher - selects and executes the appropriate command 
    public class CommandDispatcher : ICommandDispatcher
    {
        private readonly IKernel _kernel;

        public CommandDispatcher(IKernel kernel)
        {
            if (kernel == null)
            {
                throw new ArgumentNullException("kernel");
            }

            _kernel = kernel;
        }

        public async Task<CommandResult> Dispatch<TParameter>(TParameter command) where TParameter : ICommand
        {
            // Find the appropriate handler to call from those registered with Ninject based on the type parameters  
            var handler = _kernel.Get<ICommandHandler<TParameter>>();
            return await handler.Execute(command);
        }
    }

We then need to register these types with our IoC container, in this case Ninject. This will include the dispatcher classes, and setting up the registration of the query and command handlers too.


 kernel.Bind<IQueryDispatcher>().To<QueryDispatcher>();
 kernel.Bind<ICommandDispatcher>().To<CommandDispatcher>();

 kernel.Bind(x => x
  .FromAssembliesMatching("MyApp.dll")
  .SelectAllClasses().InheritedFrom(typeof(IQueryHandler<,>))
  .BindAllInterfaces());

 kernel.Bind(x => x
  .FromAssembliesMatching("MyApp.dll")
  .SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))
  .BindAllInterfaces());

Form display

The first part of the example itself requires the display of an item for editing on a form. This involves handling the request that comes into the controller action, determining the appropriate handler, executing it to populate a view model and passing this to a strongly typed view.


    // Controller action method taking a query that consists of just the Id for the item to be edited
    public async Task<ViewResult> Edit(EditViewModelQuery query)
    {
        // Populate the view model by calling the appropriate handler
        var vm = await QueryDispatcher.Dispatch<EditViewModelQuery, EditViewModel>(query);
        if (vm.Id == 0)
        {
            throw new HttpException(404, "Page not found");
        }

        return View(vm);
    }
    
    // Query handler Retrieve method implementation
    public async Task<EditViewModel> Retrieve(EditViewModelQuery query)
    {
        // Instantiate the context (if not passed to the handler, which will only be the case when unit testing)
        Context = Context ?? new ApplicationDbContext();

        // Create the view model query result
        var result = new EditViewModel();
        
        // Pull the required item from the context
        var activity = await Context.Activities
            .SingleOrDefaultAsync(x => x.Id == query.Id);
            
        // Map from the domain model object to the view model
        Mapper.Map(activityType, result);

        return result;
    }
    
    @using (Html.BeginForm("Edit", "Activities", FormMethod.Post))
    {
        @Html.LabelFor(m => m.Name)
        @Html.EditorFor(m => m.Name)
        @Html.ValidationMessageFor(m => m.Name)

        <input type="submit" value="Save" />                    

        @Html.HiddenFor(model => model.Id)    
    } 

Processing of form submission

Once the form is posted, it'll be picked up by another controller action expecting a POST input of an instance of the view model. This will be validated, and if it passes, a command object created and mapped. This command will be passed to the appropriate handler for execution and the result returned for subsequent processing.


    // Controller action method handling the form post
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit(EditViewModel vm)
    {
        // First check if view model is valid
        if (ModelState.IsValid)
        {
            // If so create the command object
            var command = new AddOrEditCommand();
            
            // Use Automapper to map from the view model to the command
            Mapper.Map(vm, command);
            
            // Call the appropriate command handler
            var commandResult = await CommandDispatcher.Dispatch(command);
            if (commandResult.Success)
            {
                // If the command is successful, we can retrieve any data returned
                var newId = (int)commandResult.Data;

                // Do stuff with the generated Id of the entity if we need to...
                    
                return RedirectToAction("Index");
            }        
            else
            {
                // Command not successful, so handle error as appropriate
            }
        }

        // View model not valid, so return to view
        return View("Edit", vm);
    }
    
    // Command handler Execute method implementation    
    public async Task<CommandResult> Execute(AddOrEditCommand command)
    {
        ValidateArguments(command);
        
        // Instantiate the context (if not passed to the handler, which will only be the case when unit testing)
        Context = Context ?? new ApplicationDbContext();

        var result = new CommandResult();
        var commandValid = false;
        Activity activity;
        
        // If a new record, create a new entity, map the command to the domain object and add it to the context
        if (command.Id == 0) 
        {
            activity = new Activity();
            Mapper.Map(command, activity);
            Context.ActivityTypes.Add(activity);
            commandValid = true;
        }
        else 
        {
            // If an updated record, retrieve it from the context and apply the updates
            activity = await Context.Activities.SingleOrDefaultAsync(x => x.Id == command.Id);
            if (activityType != null) {
                Mapper.Map(command, activity);
                commandValid = true;
            }
            else {
                result.Message = "Activity type not found.";
            }
        }
        
        if (commandValid) 
        {
        
            // Commit data  changes
            await Context.SaveChangesAsync();
            
            // Prepare result
            result.Success = true;
            result.Data = activityType.Id;
        }
        
        return result;
    }    

CQRS, Rich Domains and Unit Testing with ASP.Net MVC and Entity Framework

Having spent a bit of time working on CMS (Umbraco and EPiServer) based projects, I recently had to come back to building a custom ASP.Net application using the MVC framework. Before commencing I took a bit of time to read around, and re-think some of the ways I've built applications like this previously, in terms of how the solution is architected.

Previously I've put together a fairly strict three layered architecture - data access layer using Entity Framework, wrapped in a unit of work/repository pattern; a business logic or service layer, and the presentation web application. Which worked quite nicely in truth, but there's always value in re-looking at such things and seeing how they could be improved. And where's the fun in doing things the same way each time anyway!

In particular I was keen to investigate:

  • A CQRS style architecture, where we work with distinct query and command objects, in a more "slices over layers" fashion. This breaks the application down logically more vertically than horizontally, with features being grouped and having their own distinct classes.
  • Better following the single responsibility principle, with smaller, more focussed classes.
  • Removing the probably unnecessary wrapping of the Entity Framework context, which after all, effectively provides it's own unit of work pattern.
  • In doing so, looking to use the Entity Framework context in a more discrete fashion, avoiding potential bugs and complexities that I've run into before. These can manifest themselves if you are keeping the context alive across different operations, or attempting to handle entities created directly from form posts rather than being pulled from the context.
  • Working with a richer domain model that would play nicely both with Entity Framework and the presentation layer.
  • Increased focus on unit testing.

Credits and further reading

In working up this new architecture, nothing was invented from scratch... rather I pulled together a number of different influences from various books and blog posts that led to the patterns described in this series of posts:

Posts in this series

There will be three further posts in this series, where I'll discuss in more detail the certain aspects of the application patterns I'm now using.

Friday, 8 August 2014

Using Umbraco Mapper with Archetype (Part 2)

In the previous post I discussed a method of mapping property values from the Archetype package to a view model using Umbraco Mapper. There was still a remaining issue of how to handle picked content.

With the version of Umbraco Mapper 1.4.7 (just updated on our and NuGet) this is now possible with just some changes from the method noted in the previous post.

Firstly, you will need to have the Umbraco Core Property Value Converters package installed. If you are using Archetype you'll likely be using this already, but it's needed here to convert the values returned from Archetype node picker properties to either IPublishedContent (for single items from a content picker) or IEnumerable (for multiple items from a multi-node tree picker).

Then extending our previous example, let's say we've added fields to our "Football Match" archetype to have a content picker for the match report, and a multi-node tree picker for match reports from previous games.

Our view model then looks like this:

    public class FootballMatchesPageViewModel
    {
        public string Name { get; set; }

        public IEnumerable<FootballMatch> TodaysMatches { get; set; }
    }

    public class FootballMatch
    {
        public FootballMatch()
        {
            MatchReport = new MatchReportTeaser();
            ReportsFromPreviousGames = new List<MatchReportTeaser>();
        }

        public string HomeTeam { get; set; }

        public string HomeTeamScore { get; set; }

        public string AwayTeam { get; set; }

        public int AwayTeamScore { get; set; }

        public MatchReportTeaser MatchReport { get; set; }

        public IList<MatchReportTeaser> ReportsFromPreviousGames { get; set; }
    }

    public class MatchReportTeaser
    {
        public string Name { get; set; }

        public string Url { get; set; }
    }

Note it's important to have the constructor set the complex type and collection to an instantiated object, as the mapper won't handle mapping to null values.

The custom mapping we set up in the previous example needs some minor amends too, it's now:

    public class ArchetypeMapper
    {
        public static object MapFootballMatch(IUmbracoMapper mapper, IPublishedContent contentToMapFrom, string propName, bool isRecursive) 
        {
            var result = new List<FootballMatch>();

            var archetypeModel = contentToMapFrom.GetPropertyValue<ArchetypeModel>(propName, isRecursive, null);
            if (archetypeModel != null)
            {
                var archetypeAsDictionary = archetypeModel
                    .Select(item => item.Properties.ToDictionary(m => m.Alias, m => GetTypedValue(m), StringComparer.InvariantCultureIgnoreCase))
                    .ToList();
                mapper.MapCollection(archetypeAsDictionary, result);
            }

            return result;
        }

        private static object GetTypedValue(ArchetypePropertyModel archetypeProperty)
        {
            switch (archetypeProperty.PropertyEditorAlias)
            {
                case "Umbraco.ContentPickerAlias":
                    return archetypeProperty.GetValue<IPublishedContent>();
                case "Umbraco.MultiNodeTreePicker":
                    return archetypeProperty.GetValue<IEnumerable<IPublishedContent>>();
                default:
                    return archetypeProperty.Value;
            }            
        }
    }

Again an important point to note here is the StringComparer.InvariantCultureIgnoreCase argument to the ToDictionary call - this makes it case insensitive for key look-ups, which is handy when dealing with property aliases that are usually camel cased in Umbraco aliases but Pascal cased in C# classes.

With the latest release of Umbraco mapper, there's a small update to the routine that maps from a dictionary as we are using here. It checks on the types, and if they are found to be IPublishedContent or IEnumerable the mapping routine those types is run for that property - thus allowing them to be mapped in exactly the same way as if we were just mapping the content directly.

Thursday, 7 August 2014

Using Umbraco Mapper with Archetype

A post came up today on the Umbraco forum discussing use of the Umbraco Mapper package I've built with colleagues at Zone, and everyone's favourite new package, Archetype. We haven't had chance to work with Archetype as yet, but are planning to use it on an upcoming project, so it seemed a good idea to work out the best way for these two packages to play together.

It's a little tricky to begin with as Umbraco Mapper is primarily about mapping from IPublishedContent - single Umbraco nodes or collections picked from a node picker or pulled together via a node query - to strongly typed view models.

However it also supports mapping from a simple dictionary of strings and objects - Dictionary<string, object> - and that, along with the ability to define custom mappings for a particular view model type, means this can be done fairly cleanly.

Note: haven't found a clean way to handle picked content yet - e.g. from content picker or multi-node tree picker... will update if and when we do.. This is supported now - see the follow-up post.

To take an example, let's say I'm creating a page to display a list of football results, and so have created an archetype to represent a series of matches:

I've then created a view model to represent this information:

    public class FootballMatchesPageViewModel
    {
        public string Heading { get; set; }

        public IEnumerable TodaysMatches { get; set; }
    }

    public class FootballMatch
    {
        public string HomeTeam { get; set; }

        public int HomeTeamScore { get; set; }
            
        public string AwayTeam { get; set; }

        public int AwayTeamScore { get; set; }
    }

Which will be rendered in my view template like this:

    <h3>Today's Matches</h3>

    @foreach (var match in Model.TodaysMatches)
    {
        
@match.HomeTeam @match.HomeTeamScore v @match.AwayTeamScore @match.AwayTeam
}

As it stands, Umbraco Mapper won't know how to handle mapping to the IEnumerable<FootballMatch> as it's a type it knows nothing about. We can rectify this by setting up a custom mapping. You add this code just after where you have instantiated the mapper, probably best in a base controller so all custom mappings can be initialised in one place.

    Mapper.AddCustomMapping(typeof(IEnumerable<FootballMatch>).FullName, 
        ArchetypeMapper.MapFootballMatch);

And then we need to write the function that will handle the mapping for the given type:

    public class ArchetypeMapper
    {
        public static object MapFootballMatch(IUmbracoMapper mapper, IPublishedContent contentToMapFrom,
            string propName, bool isRecursive) 
        {
            var result = new List<FootballMatch>();

            var archetypeModel = contentToMapFrom.GetPropertyValue<ArchetypeModel>(propName, isRecursive, null);
            if (archetypeModel != null)
            {
                var archetypeAsDictionary = archetypeModel
                    .Select(item => item.Properties.ToDictionary(m => FirstCharToUpper(m.Alias), m => m.Value));
                mapper.MapCollection(archetypeAsDictionary, result);
            }

            return result;
        }

        private static string FirstCharToUpper(string text)
        {
            return text.Substring(0, 1).ToUpper() + text.Substring(1);
        }
    }

The trick here as you can see is that we are taking the strongly type ArchetypeModel, converting it to a dictionary and the utilising the mapper to map to the view model.

With that in place, the view model will be mapped as required and the football match results will be displayed in the view.

Thanks to Shinsuke and Raffaele for raising the questions and coming up with most of the answers!

See part 2 for details on handling mapping of content pickers used in an Archetype.

Another possible approach

What's also interesting here is that we are using Umbraco Mapper to effectively map from one strongly typed model to another - albeit via a dictionary. And that rings some bells for me - i.e. AutoMapper. This is a tool I've used on many projects outside of Umbraco for mapping from domain models to view models and between other types - it was trying to replicate this within Umbraco that led to the development of Umbraco Mapper.

So if preferred, you could certainly utilise AutoMapper here, to go from the Archetype model to the view model. For me I'm OK with going via the dictionary as above, and perhaps having two mapping components in one project could get a bit confusing. But given we are moving into the world of strongly typed models with Umbraco these days via the property value converters, it's certainly another approach worth considering.