Recent Articles

RavenDB, UnitOfWork and MVC - revisited

Written by Arnold Zokas on on topic of Databases.

I recently blogged about implementing RavenDB UnitOfWork in ASP.NET MVC applications. My recent refactoring session prompted me to rethink my approach.

Why?

Global.asax is not a dumping ground

I think of Global.asax as the place where infrastructure initialisation happens. In this case I was also using it to manage IDocumentSession lifetime. Violation of Single Responsibility Principle. Messy.

Inefficient

In MVC, all requests (even those for static resources) pass through the ASP.NET request pipeline. This means every css, js and image request was triggering HttpApplication.EndRequest event. Whilst it wasn't a big drain on performance, I wanted to do away with it.

Bad error handling

I contacted Ayende to get his opinion and he correctly pointed out runtime exceptions were not being handled properly. IDocumentSession.SaveChanges() was being called for all requests (even those that resulted in an exception).

There is a better way to do it

I still wanted this to be handled automatically by the infrastructure, so I looked at my requirements and decided that:

  • Creation of IDocumentSession can be handled by StructureMap: I already use it for other purposes and it provides some really nice caching options
  • Custom controller factory can be used to inject IDocumentSession any other dependencies into the controller
  • Globally-registered action filter can be used to commit any changes in IDocumentSession

StructureMap registry

public sealed class StructureMapConfigurationRegistry : Registry
{
    public StructureMapConfigurationRegistry()
    {
        // register RavenDB document store
        ForSingletonOf<IDocumentStore>().Use(() =>
        {
            var documentStore = new EmbeddableDocumentStore();
            documentStore.ConnectionStringName = "RavenDBIsAwesome"
            documentStore.Initialize();

            return documentStore;
        });

        // register RavenDB document session
        For<IDocumentSession>().HybridHttpOrThreadLocalScoped().Use(context => 
        {
            return context.GetInstance<IDocumentStore>().OpenSession();
        });
    }
}

Custom controller factory

public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext context, Type type)
    {
        return ObjectFactory.GetInstance(type) as Controller;
    }
}

Global action filter

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class RavenSessionAttribute : FilterAttribute, IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Exception != null)
            return; // don't commit changes if an exception was thrown

        using (var session = ObjectFactory.GetInstance<IDocumentSession>())
            session.SaveChanges();
    }
}

Bringing it all together…

public class MvcApplication : HttpApplication
{
    public void Application_Start()
    {
        // register global filters
        GlobalFilters.Filters.Add(new RavenSessionAttribute());

        // initialise StructureMap
        ObjectFactory.Initialize(ie => ie.AddRegistry<StructureMapConfigurationRegistry>());

        // register controller factory
        ControllerBuilder.Current.SetControllerFactory(typeof(StructureMapControllerFactory));

        // register routes, etc
    }
}

What I like:

  • Simple: easy to read and maintain
  • Testable: clear behaviour, low coupling
  • Clean: doesn't require use of common base classes or similar mechanisms
  • Slightly more efficient than my previous implementation: requests for static resources are no longer affected

What I don't like:

  • IDocumentSession lifetime management split across two classes

What are your thoughts? Can it be done better?

RavenDB and the Repository pattern

Written by Arnold Zokas on on topic of Databases.

I recently had a short email exchange with Ayende Rahien and he suggested something I hadn't considered before: not using a Repository pattern.

Background

Allow me to elaborate. Before trying RavenDB, I was frequently dealing with data APIs that necessitated use of the Repository pattern (or at least some pattern of abstraction):

  • Legacy APIs: legacy APIs often expose data in a format very different to your domain model. Translation of legacy data model to domain model should occur in one place and one place only
  • Web services: a lot commercial web services are an absolute mess and you want to avoid exposing them to the rest of the application as much as possible
  • Sitecore Data API: majority of CRUD and field access operations involve magic strings and you don't want those dotted all over your application

Reasons for using layers of abstraction boil down to:

  • Impedance mismatch between you data source and your domain model
  • Badly designed APIs
  • Aversion to magic strings
  • Other reasons exist, but these three are enough to demonstrate my point

I was so used to dealing with these issues that trying to shoehorn RavenDB into a repository just seemed natural. I didn't give it much thought until I spoke to Ayende.

Why you should not use Repository pattern with RavenDB

I wanted to know how this approach would work in real-life. I branched my website's local Git repository, removed all repositories and all the infrastructure that supported it. Now I get what Ayende meant:

  • There is no impedance mismatch: when you ask RavenDB to store some data — you give it an instance of your domain model. When read that data back out, it is returned to you as an instance of your domain model. There are no properties to map, it works automatically
  • Well-designed API: considering the underlying complexity, probably one of the best I have worked with
  • No magic strings: earlier builds of RavenDB did use strings in some places, but that is no longer the case. Current API uses LINQ and lambda expressions, which makes it very refactor-friendly

Here is an example. This was the old API:

public class BlogPost
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTimeOffset PublishedOn { get; set; }
}

public interface IRepository<T>
{
    T GetById(int id);
}

public interface IBlogPostRepository : IRepository<BlogPost>
{
    IList<BlogPost> GetRecentBlogPosts();
}

public abstract class Repository<T>
{
    protected readonly IDocumentSession Session;

    public Repository(IDocumentSession session)
    {
        Session = session;
    }

    public virtual T GetById(int id)
    {
        return Session.Load<T>(id);
    }
}

public class BlogPostRepository : Repository<BlogPost>, IBlogPostRepository
{
    public BlogPostRepository(IDocumentSession session) : base(session)
    {
    }

    public IList<BlogPost> GetRecentBlogPosts()
    {
        var blogPosts = Session.Query<BlogPost>
                               .OrderByDescending(bp => bp.PublishedOn)
                               .ToList();

        return blogPosts;
    }
}

public class BlogController : Controller
{
    private readonly IBlogPostRepository _repository;

    public BlogController(IBlogPostRepository repository)
    {
        _repository = repository;
    }

    public ActionResult ViewBlogPost(int id)
    {
        var blogPost = _repository.GetById(id);

        return View(blogPost);
    }

    public ActionResult ViewRecentBlogPosts()
    {
        var blogPosts = _repository.GetRecentBlogPosts();

        return View(blogPosts);
    }
}

Wow, that's a lot of code just to do a couple of simple queries. This is the new API:

public class BlogPost
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTimeOffset PublishedOn { get; set; }
}

public class BlogController : Controller
{
    private readonly IDocumentSession _session;

    public BlogController(IDocumentSession session)
    {
        _session = session;
    }

    public ActionResult ViewBlogPost(int id)
    {
        var blogPost = _session.Load<BlogPost>(id);

        return View(blogPost);
    }

    public ActionResult ViewRecentBlogPosts()
    {
        var blogPosts = _session.Query<BlogPost>
                                .OrderByDescending(bp => bp.PublishedOn)
                                .ToList();

        return View(blogPosts);
    }
}

Can you spot the difference? The repository-free approach brings with it a number of advantages:

  • Less code: you can write and refactor features a lot quicker
  • Easier to read and understand: logic does not span multiple files and there are no inheritance hierarchies to deal with
  • Easier to test: just test the class that does the query. Thanks to In-Memory mode, you can execute tests without having to mimic the database
  • Handles requirement changes more elegantly: given a requirement to limit number of results returned by GetRecentBlogPosts to 10, how would you handle that in a repository? Add a parameter? Create an overload? Will you have to keep creating new overloads whenever new requirements are presented? Using the new approach, the query logic is isolated and can be change independently of the rest of the application
  • Allows use of advances APIs: for example you can enable aggressive caching on ViewBlogPost(id) in a way that does not affect the rest of the application

When you take above points into consideration, do you really want to use an abstraction?

But what about…

By now you may be thinking: "Hold on a sec. My application is different. I really need that extra layer". I have picked out three common concerns people have about this.

What if later I decide to switch to a relational database?

Relational databases and document databases have very different modelling requirements. You will have to not only rewrite the data access portion of your code, but also adjust internal repository APIs to handle the new reality.

Also, remember this is a strategic decision and doesn't happen overnight (if it does where you work - I feel sorry for you).

What if I later decide to switch to another document database?

Switching to another database is no simple task even if it belongs to the same family of databases. Expect to be dealing with a different API, usage patterns and optimisations. Repository pattern doesn't protect you from that. You still have to rewrite code. You still can't use the advanced features because you are shackled by a layer of abstraction.

Won't this lead to a lot of code duplication?

It won't. Providing you use RavenDB correctly. I have seen plenty examples where people initialise a new DocumentSession for every CRUD operation. Don't do that — session lifetime management is an infrastructure concern and should be handled at different level. Initialise your session once, at the beginning of HTTP request. Close your session at the end of HTTP request. Reuse it across all operations. This way your code is simply performing a CRUD operation and there is nothing else to think about. This also allows RavenDB to optimise writes (via batching) and makes unit testing simpler.

Sometimes it is ok to use abstractions

I am not saying you should never ever use layers of abstraction with RavenDB. If you have good reasons, then by all means go ahead. I just want you to consider next time whether the need to use abstractions outweighs the advantages of using RavenDB API directly.

Looking back at 2011

Written by Arnold Zokas on on topic of Meta.

Another year begins and this is a good opportunity to look back at memorable aspects of 2011.

Developed and launched first client website

Aside from a few small projects, 2011 was occupied developing ScottDunn.com. It was a fun project with a great team and I have learned a lot from it.

Developed new website and blog

This has been on my list for a long time, so I am very pleased I had some time to set it up. It is far from finished. Lots of outstanding tasks on my backlog, so this will keep me busy for a while.

Learned a lot

Through projects, books and blogs I have learned a lot of new tools and techniques:

  • Sitecore customisation, performance optimisation and security hardening
  • HTML 5, HTML 5 Boilerplate, CSS 3
  • Lots of new jQuery techniques and Backbone.js
  • Website performance optimisation
  • MVC 3
  • RavenDB

I also took some time out to attend CodeKen 2011 and met Jon Skeet, Stefan Plattner and many other respected professionals.

Kindle has revolutionised the way I read books

I bought my first Kindle (3rd generation WiFi model) almost a year ago. I read more books now than I have ever done. In the past year I have read 19 books: 10 technical + 9 non-technical. Ebooks are a lot cheaper and I was rapidly running out of physical storage space, so getting a Kindle has paid off in many ways.

Good time management is very important

One of the reasons I started my own company was so I could invest more time in personal projects. I underestimated just how much time non-technical part of operating a business would absorb. I had to adapt (and fast), so I experimented lots and came up with a more manageable way handle routine tasks:

I also unsubscribed from all non-essential email notifications, cleaned-up RSS feed subscriptions and pretty much stopped watching TV.

2012 will be even better

I have lots in mind for 2012:

  • Continue improving my skills: very interested in RavenDB and Sitecore Customer Engagement Platform and Umbraco (version 5 with Razor support is coming out soon).
  • Contribute to an open-source project: I am considering RavenDB, SquishIt, Noda Time and Lucene.net
  • Develop and launch my own open-source project: haven’t quite decided what I am going to do yet (lots of ideas though)
  • Read 26 books: two per month (at least 50% technical content)
  • Post 26 articles: two articles per month (not counting meta articles such as this one)

How to implement Raven DB UnitOfWork in an ASP.NET MVC application

Written by Arnold Zokas on on topic of Databases.

I have been looking at ways to implement UnitOfWork pattern for RavenDB. I have come across three implementations, but in the end decided to roll my own.

I have posted an update to this blog post. Please check it out.

The purpose of this is not to criticize other people, but come up with an alternative approach. Existing solutions mentioned here do work and can be used.

Implementation #1

Shiju Varghese’s NoSQL with RavenDB and ASP.NET MVC - Part 1 is the least complicated of the three, but I have a few of issues with it:

  • Bad IDocumentSession lifetime management: IDocumentSession lifetime is controlled via HttpApplication BeginRequest/EndRequest event handlers. This makes unit testing complicated
  • IDocumentSession is exposed as a static property of HttpApplication and referenced by repositories: a repository should not have a dependency on HttpApplication. Dependencies like that should be managed via constructor/property injection
  • Calls to IDocumentSession.SaveChanges() method at repository level: which prevents RavenDB from optimising write operations when you make multiple inserts/updates/deletes within a single HttpRequest. SaveChanges() should, in most cases, be called only once and at the end of the request

I have been using RavenDB for about 5 hours, so my understanding of its inner workings could be completely wrong. Feel free to point out any errors in the comments.

Implementation #2

Justin Schwartzenberger’s Embedding RavenDB into an ASP.NET MVC 3 Application takes the shared base Controller class approach.

I find using custom Controller base class to handle IDocumentSession lifetime messy. It breaks Single Responsibility Principle. The controller should not be responsible for lifetime management of its dependencies. This is an infrastructure concern and should be handled elsewhere.

Implementation #3

Primary Objects’ Generating Flying Creatures in NoSQL RavenDB with C# ASP .NET MVC Razor is the top ranking result for Google search (ravendb+unitofwork+mvc). It is very close to what I need, but has some unwanted characteristics:

  • Wrappers, wrappers and more wrappers: you don't need a UnitOfWork wrapper with RavenDB. The same lifetime management logic can be handled by a properly configured IOC/DI framework
  • Weighty Repository pattern implementation: I like my repositories lean: plain class with some get/put/delete methods
  • Calls to IDocumentSession.SaveChanges() method at repository level: same comments as Implementation 1

Requirements

I am looking for a solution that:

  • Disposes RavenDB IDocumentSession automatically at the end of the HttpRequest
  • Calls IDocumentSession.SaveChanges() automatically at the end of the HttpRequest
  • Does not rely on custom Controller base class
  • Is testable and with 100% coverage
  • Is clean (self-contained)
  • Is simple (no wrappers)

Alternative implementation

Borrowing some concepts from other solutions, I have put together a basic implementation that satisfies these requirements. I am using StructureMap, but this can probably be easily replicated with any other IOC/DI frameworks.

public class MvcApplication : HttpApplication
{
    public void Application_Start()
    {
        // initialise StructureMap
        ObjectFactory.Initialize(iex =>
        {
            iex.ForSingletonOf<IDocumentStore>()
               .Use(DocumentStoreFactory.CreateDocumentStore());

            iex.For<IDocumentSession>()
               .HybridHttpOrThreadLocalScoped()
               .Use(c =>
               {
                   c.GetInstance<IDocumentStore>().OpenSession())
               };
        });
		
        // register global filters, register routes, etc...
    }

    public void Application_EndRequest()
    {
        var model = ObjectFactory.Container.Model;
        var reference = model.InstancesOf<IDocumentSession>().Single();

        if (reference.ObjectHasBeenCreated() == false)
            return; // object was not constructed so there is nothing to do

        var documentSession = ObjectFactory.GetInstance<IDocumentSession>();
        documentSession.SaveChanges();
        documentSession.Dispose();
    }
}
public static class DocumentStoreFactory
{
    public static IDocumentStore CreateDocumentStore()
    {
        var documentStore = new DocumentStore();
        documentStore.ConnectionStringName = "Raven";
        documentStore.Initialize();

        return documentStore;
    }
}
public class SampleRepository : ISampleRepository
{
    readonly IDocumentSession _documentSession;

    public SampleRepository(IDocumentSession documentSession)
    {
        _documentSession = documentSession;
    }

    public void UpdateSomething(Something something)
    {
        documentSession.Store(something);
    }
}

For implementation and test examples have a look at novuscraft.com Git repository.

Hello, Raven DB

Written by Arnold Zokas on on topic of Databases.

Until now, I have all articles on this blog were just hard-coded into the page. I finally managed to find some time to have a good think about my persistence strategy. RavenDB has been on my radar since it was first announced by Ayende, but I had no opportunity to use it until now.

This is my first RavenDB implementation and so far I am pleased with the way it is going:

  • RavenDB is very easy to pick up and just feels natural: The impedance mismatch you encounter with relational databases is noticeably absent. It took me just over an hour to implement basic display blog post functionality
  • Infrastructure setup is minimal: It took about 15 lines of code to implement including UnitOfWork and StructureMap wiring, excluding specifications and the usual IRepository scaffolding
  • It is incredibly fast: I am running it in embedded mode, which means there is no network cost.
  • There is a strong community growing around it: This is evidenced by StackOverflow, Google and Google Groups activity.
  • The project has great visibility: it is available publicly on GitHub, so you can play around with the source and post bug reports. I have contacted Ayende on couple of occasions and he replies very quickly, the man never rests.

One thing worth mentioning is the API is constantly evolving, so you will inevitably encounter outdated articles and code samples. Don't get discouraged: API features often change shape, but rarely get removed. Ask people on Google Groups and StackOverflow and you will be impressed by how quickly you get an answer.

Getting started with MSpec

Written by Arnold Zokas on on topic of Testing.

I am a long-time fan of xUnit.net. I have been using it since it was in early beta and it is my default choice for almost any project. For building Novus Craft, I decided to use something new and very different — a Context/Specification framework called Machine.Specifications.

On my journey to learn MSpec, I have come across a number of helpful tips, instructions and tweaks, so I decided to put together a quick guide on how to get started. I am not going to talk about why or when you should use MSpec. If you want to read about that, check out Aaron Jensen’s Introducing Machine.Specifications (or MSpec for short). Instead, I will focus on how to setup your development environment.

How to get MSpec

You have three options:

1. Install MSpec via NuGet package manager

The quickest option is to install using NuGet

Open NuGet Package Manager Console and enter one of the following commands:

  • To download and install an unsigned release:
    PM> Install-Package Machine.Specifications
  • To download and install a signed release:
    PM> Install-Package Machine.Specifications-Signed

2. Download latest MSpec binaries from CodeBetter CI server

If you don't use Nuget, you can download the latest build directly from CodeBetter Continuous Integration server:

3. Compile MSpec yourself from source available on GitHub

MSpec is an open-source project, so you can simply pull down the latest source using Git and compile it yourself. This is useful if you want to add private customisations or try out a new feature before it is released publicly. Check out MSpec readme file for more information.

How to setup MSpec with ReSharper

If you use something other than ReSharper you can skip this stage. If you are not using ReSharper or any other productivity plugin — install ReSharper right now (you will thank me later).

Install ReSharper runner

Out of the box, ReSharper has no knowledge of what an MSpec is, but it does have an extensibility API. To enable MSpec support you need to install a ReSharper plugin.

MSpec provides plugins compatible with ReSharper v4.1, v4.5, v5.0, v5.1, v6.0 for Visual Studio 2008 and 2010. To install the plugin you need to open MSpec installation directory and execute on the following scripts:

  • ReSharper v4.1
    InstallResharperRunner.4.1.bat
  • ReSharper v4.5
    InstallResharperRunner.4.5.bat
  • ReSharper v5.0 on Visual Studio 2008
    InstallResharperRunner.5.0 - VS2008.bat
  • ReSharper v5.0 on Visual Studio 2010
    InstallResharperRunner.5.0 - VS2010.bat
  • ReSharper v5.1 on Visual Studio 2008
    InstallResharperRunner.5.1 - VS2008.bat
  • ReSharper v5.1 on Visual Studio 2010
    InstallResharperRunner.5.1 - VS2010.bat
  • ReSharper v6.0 on Visual Studio 2008
    InstallResharperRunner.6.0 - VS2008.bat
  • ReSharper v6.0 on Visual Studio 2010
    InstallResharperRunner.6.0 - VS2010.bat
  • ReSharper v6.1 on Visual Studio 2008
    InstallResharperRunner.6.1 - VS2008.bat
  • ReSharper v6.1 on Visual Studio 2010
    InstallResharperRunner.6.1 - VS2010.bat

Configure ReSharper Naming Rules for MSpec

One of the things you will notice straight away is ReSharper doesn't like MSpec naming conventions. Fortunately, you can configure ReSharper to understand MSpec naming conventions and even warn you when you are not naming you specifications correctly. Derek Greer’s article (Resharper Naming Style for Machine.Specifications) explains how to do this correctly.

Suppress ‘Field is never used’ warnings

MSpec specifications are defined using private fields. MSpec uses reflection to analyse specifications at runtime, so naturally there are no references to those private fields. Visual Studio’s code analysis engine reports them as unused (this behaviour is by design and is correct).

You can override this behaviour via project properties. This approach works at project-level and does not affect other projects in the solution:

  1. Open Properties for your MSpec project
  2. Select Build tab
  3. Enter 169 into Supress warnings field
  4. Save (this will take immediate effect)

Other Resources

I hope you found this information useful. There are lots of other resources available. Check out Byron Sommardahl’s How to MSpec? for useful links. Another good place to learn more about MSpec is StackOveflow.

Welcome to my blog

Written by Arnold Zokas on on topic of Meta.

I have been wanting to set one up for a while, but for various reasons kept postponing. One of the things that prompted me to start a blog is my desire to learn ASP.NET MVC. I could not think of a better way to learn than building a website/blog from scratch.

Currently, the "blog engine" is just a skeleton implementation constructed with ASP.NET MVC 3 (C# 4 + Razor views) and HTML5 + CSS3 + jQuery. Source code is available publicly on GitHub.

My other reason for starting a blog is I want need a place where I can share my discoveries and ideas. It bugs me that whenever I have solved a rare challenge (rare in a sense Google had no answer to it), I have not shared the solution.

Right now my backlog is pretty full (I want to integrate RavenDB, SquishIt, and more), so this little project should keep me busy for a while.