Nov 22, 2011

Implementing Repository with NHibernate

In spite of common now approach of using in memory data base for unit testing NHibernate related code I still do like to have repository. The reason for that is simplicity. In most applications transactions are managed separately, either via action filters or HTTP modules. So in unit test you need to repeat logic not for just creating of object graph, but for saving it also.

What I always wanted is ability to write code like this in tests:

var product = new Product {
    Price = 100,
    Name = "Test"
};

product.Category = new Category {
    Name = "Food"
};

IRepository<Product> products = new List<Product>();

And all the logic for testing queries can be done with LINQ to objects (you will need integration tests to verify real query generated by the ORM). No need for huge test setup and so on.

With release of on NH 3 LINQ provider was greatly improved (but still has a lot of troubles). In this post I’m going to show implementation of Repository described in Fabio’s post. The main idea described there is that IRepository interface should just look like this:

/// <summary>
/// Repository for basic entities persistence actions
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IRepository<T> : ICollection<T>, IQueryable<T>
    where T : Entity
{
    T Get(long id);
}

The only additional method is Get. Its just useful in a lot of cases. Everything else is provided with mentioned interfaces. Implementation from NHibernate point of view is pretty straight forward and I won’t describe it, you can see in the project sample. The interesting part is mocking one. Here is code for one of the methods:

public class FakeRepository<T> : List<T>, IRepository<T>
    where T : Entity
{
    public FakeRepository(IEnumerable<T> products) : base(products)
    {
    }

    public Expression Expression
    {
        get
        {
            return ((IEnumerable<T>)this).Select(x => x).AsQueryable().Expression;
        }
    }
}

So now we can implement test like this:

[Test]
public void Repository_can_be_created_from_simple_list()
{
    Product product = new Product();
    
    List<Product> products = new List<Product>();
    products.Add(product);

    IRepository<Product> repository = new FakeRepository<Product>(products);

    Assert.That(repository, Is.Not.Empty);
}

And it will pass. Also all production code can do any sort of LINQ queries and they will succeed.

The last and probably the most scary thing - fetching. LINQ to NHibernate has Fetch and FetchMany extension methods. But when you use them on regular list exception is thrown:

System.InvalidOperationException : There is no method 'Fetch' on type 'NHibernate.Linq.EagerFetchingExtensionMethods' that matches the specified arguments

So we need to abstract fetching away. In order to do that, we will need our own Fetch and FetchMany methods and IFetchRequest interface with the following signature:

public interface IFetchRequest<TQueried, TFetch> : IOrderedQueryable<TQueried> 
{
}

Instance of this interface will be returned as a result of calls to our new extension methods, that look like this:

public static class EagerFetch
{
    public static IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(this IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
    {
        return FetchingProvider().Fetch(query, relatedObjectSelector);
    }

    // ... other methods

    public static Func<IFetchingProvider> FetchingProvider = () => new NhFetchingProvider();
}

I’m showing only method here, others are implemented in the same way (and yes, it is ugly). But the good news is that you write it once, and forget. Interesting part is FetchingProvider that performs fetching itself. The instance of provider is provided by Func, that means that in tests you can easily change provider instance. With such code somewhere in test fixture setup:

EagerFetch.FetchingProvider = () => new FakeFetchingProvider();

Implementation of NHibernate provider is on the github (together with fake provider). FakeProvider in its turn just doing nothing. But in theory we can mock it and set some verifications, but I don’t think it’s a good idea.

Full source code with working solution you can find on the github.

Oct 21, 2011

Setup SQL Server Compact 4 to unit test NHibernate related code

Most of the time to fake data base SQL lite data base is used. But it has certain differences from SQL server. With release of SQL Compact 4 it becomes really good choice to mock data base calls. So in this post I will describe a way of setting up NHibernate to work with SQL CE local data base. So here are our goals:

  1. Each test fixture has its own fresh DB instance
  2. NHibernate SessionFactory is same for all the tests (performance is still important in tests)
  3. Caching of NHibernate doesn’t stands on isolation way (each test will have clean factory, without any cached entities)
  4. Works just after getting from source control with no additional configuration

First of all we need to install sql ce tools for visual studio. After done that we can add an empty data base file to our tests project:

Sql server compact 4.0 local data base

lets call it db. This file is going to be the one that is going to be copied for each test and where NHibernate will create its tables.

Now lets create a base class for tests that are going to use NHibernate:

public class DbTests
{
    protected static ISessionFactory factory;
    static Configuration nhConfig;

    static DbTests()
    {
        File.Copy("db.sdf", "Temp.sdf", true);
        nhConfig = NhConfigure();
        factory = nhConfig.BuildSessionFactory();
    }

    [TestFixtureSetUp]
    public void Setup()
    {
        File.Copy("db.sdf", "Temp.sdf", true);
        new SchemaExport(nhConfig).Execute(true, true, false);
    }

    [TestFixtureTearDown]
    public void TearDown()
    {
        File.Delete("Temp.sdf");
    }

    static Configuration NhConfigure()
    {
        DomainMapper mapper = new DomainMapper();
        HbmMapping mappings = mapper.CompileMappingFor(new[] { typeof(TestEntity) });

        var configuration = new Configuration();
        configuration.SessionFactory()
            .Integrate.Using<MsSqlCe40Dialect>()
            .Connected.By<SqlServerCeDriver>()
            .Using("Data Source=Temp.sdf");

        configuration.AddDeserializedMapping(mappings, "domain");
        
        return configuration;
    }
}

What is done here is pretty straight forward. Each test fixture will get its own empty data base with new schema installed.

Also you will need to install SqlServerCompact package from nuget in order to get SqlServerCeDriver support.

There is an interesting bug when using identity columns with SQL CE. You can get NHibernate.AssertionFailure : null identifier exception. Here is how you can solve it.

The last thing we want to take care about is NHibernate cache. Each test probably will have its own ISession instance, so only second level caching should be handled. Here is how we can clean up it:

static void ClearCache()
{
    factory.EvictQueries();
    foreach (var collectionMetadata in factory.GetAllCollectionMetadata()) 
        factory.EvictCollection(collectionMetadata.Key);
    foreach (var classMetadata in factory.GetAllClassMetadata()) 
        factory.EvictEntity(classMetadata.Key);
}

Just add this method call to Setup and that it. As always working sample attached:

Source code sample doesn’t contain nuget packages and uses this way of working. So don’t be scared of everything red in ReSharper after open solution. Just build it.

Oct 7, 2011

Getting started with knockout.js

Recently I’ve had some time to learn knockout.js. It’s a javascript library for building rich internet applications. In spite of wonderful tutorials section on main site learning wasn’t as smooth as I would like it to be. Mainly because of some changes in 1.3 version and version 1.2 (that is currently used for tutorials).

Before reading further I would suggest you to watch a great video about knockout.js. After seeing it I’m not sure that you need to read further Smile.

Now we are going to build an editing form for Northwind data base products. The desired result is the following form:

Products editing form

So when page is loaded only categories list is visible at the left. When user selects category, list of products is shown where user is able to select concrete product to edit and save.

So lets create a new ASP.NET MVC 3 internet web application. As data access layer we’ll use Entity Framework. So add new ADO.NET Entity Data Model, name it Northwind and point to your DB instance.

To get started we need a list of categories, so navigate to HomeController and add the following code to Index action:

public ActionResult Index()
{
    using (Northwind context = new Northwind())
    {
        var categories = context.Categories.Select(c => new {c.CategoryID , c.CategoryName}).ToList();
        ViewBag.Categories = categories;

        return View();
    }
}

That’s it for now on server side. Now navigate to Index.cshtml view where everything interesting is going to happen. In order to get knockout working execute next nuget command: Install-Package Knockoutjs. It will download latest version of knockout library and place it under Scripts folder. Include it in your view.

First of all we need to render a list of categories. Knockout 1.3 has build in ability to generate html based on template. So to render list of categories add the following html with javascript on view:

<ul data-bind="foreach: categories">
    <li>
        <a data-bind="text: $data.CategoryName"
            href="javascript:void(0);">
        </a>
    </li>
</ul>
<script type="text/javascript">
   var viewModel = {
        categories: @Html.Raw(Json.Encode(ViewBag.Categories))
    };
   ko.applyBindings(viewModel);
</script>

It will render li with anchor for each category that came from server. Notice that in order to get JSON representation of categories list Json.Encode method is used.

On this small example we already can see the MVVM pattern in action. View is bounded to model that is stored in js objects. So how we have strong separation of data from its representation even on client side. We can apply unit testing of javascript without messing with UI and have all the procs of concerns separation (e.g. build other UI for mobile devices).

Now lets work with some events. We want to show products when some category is selected. Lets create a server side logic for retrieving products in category. Add a new controller like this:

public class ProductsController : Controller
{
    public ActionResult InCategory(int id)
    {
        using (Northwind context = new Northwind())
        {
            var result = context.Products.Where(x => x.CategoryID == id)
                                         .Select(p => new {p.ProductID, p.ProductName})
                                         .ToList();

            return Json(result, JsonRequestBehavior.AllowGet);
        }
    }
}

So when category is clicked we should somehow call this method and show returned results. Lets add a method for our view model that should be called when category is selected and bind click event to it. Here what we should get:

<a data-bind="text: $data.CategoryName,
              click: function(){ viewModel.selectCategory($data.CategoryID); }"
    href="javascript:void(0);">
</a>
<script type="text/javascript">
   var viewModel = {
        categories: @Html.Raw(Json.Encode(ViewBag.Categories)),
        selectCategory: function(categoryId) {
               console.log(categoryId);
        }
   };
   ko.applyBindings(viewModel);
</script>

Now if you open FireBug and refresh a page when you click on category you will see its id being printed in console.  Now lets store selected category id (we will need it further in tutorial). In order to do it, lets add a new property for viewModel and set in selectCategory method:

selectedCategory: ko.observable(),
selectCategory: function(categoryId) {
    this.selectedCategory(categoryId);
}

Couple of things needs to be noticed here: initial value of the selectedCategory is ko.observable – it will create an empty value, but when this value is changed all interested in it parts of application will be notified. Second thing is that assigning value is done not via =, but with calling that property and passing value. Now we are ready to display list of products. In order to do it lets add a table template:

<table>
    <thead>
        <th>
            ProductName
        </th>
    </thead>
    <tbody data-bind="foreach: products">
        <tr>
            <td>
                <a data-bind="text: $data.ProductName"
                   href="javascript:void(0);">                    
                </a>
            </td>
        </tr>
    </tbody>
</table>

So we have a table that is bound to the products field of view model. Now we need fill this collection:

viewModel.products = ko.observableArray([]);

ko.dependentObservable(function() {
    if(this.selectedCategory()) {
       $.get('@Url.Action("InCategory", "Products")/' + this.selectedCategory(), this.products);
    }
}, viewModel);

With the help of dependentObservable method we can create a property that is going to change when another property changes. Knockout will figure out by himself that this method should be called when selectedCategory method is called. So now you should have working list of categories with ability to view products in it.

Next step is displaying and edit form. Steps should be already familiar. Lets add a server side method for retrieving order by its id:

public ActionResult Get(int id)
{
    using (Northwind context = new Northwind())
    {
        var result = from p in context.Products
                     where p.ProductID == id
                     select new { p.ProductID, p.UnitPrice, p.ProductName, p.UnitsInStock, p.UnitsOnOrder };
        return Json(result.FirstOrDefault(), JsonRequestBehavior.AllowGet);
    }
}

And on the client side:

viewModel.selectedProductId = ko.observable();
viewModel.selectedProduct = ko.observable(‘’);

viewModel.selectProduct = function(productId) {
  viewModel.selectedProductId(productId);
};

ko.dependentObservable(function() {
     if(this.selectedProductId()) {
         $.get('@Url.Action("Get", "Products")/' + this.selectedProductId(), this.selectedProduct);
     }
}, viewModel);

After binding a click event of product anchor to selectProduct method we need last thing to do – implement template for editing:

<fieldset>
    <legend data-bind="text: selectedProduct().ProductName">       
    </legend>
    <dl>
        <dt>
            Product name
        </dt>
        <dt>
            <input type="text" name="ProductName" data-bind="value: selectedProduct().ProductName" />
        </dt>
    </dl>
</fieldset>

So now user is able to select category and product. I won’t cover saving data to db in this tutorial. Lets add some nice features. For example we want to highlight selected category and selected product in order to show user where he is now. Lets add a new style called current:

.selected
{
    background-color: Aqua;
}

And we want apply it to current category and product. Now we can do it with just only bindings:

css: {selected: $data.CategoryID === viewModel.selectedCategory()}
css: {selected: $data.ProductID === viewModel.selectedProductId()}

First one goes for category anchor template, second one is for product item template in list.

Full source code for this example:

Sep 30, 2011

Yet another scripts and styles combining and minification in ASP.NET

In recent project we had to optimize application for mobile devices with slow internet connection. Obviously among other we need to combine, minify and gzip scripts/styles to reduce their size. And that’s how project I’m going to describe here has started. Its free, open source and hosted on bitbucket.

Examples on how to use it you can find on the wiki page. Here I want describe a little about how it it done and how it works.

nuget

Of course I’ve created a nuget package Smile. During installation it registers required http handler and creates required configuration section. The only issue I can see here is that when you are going to update on new versions it may reset your adjustments in configuration. But currently its not a lot of them so you can restore it.

Rendering

During debug mode all the scripts/styles references will be outputted separately and non minified. Its useful for debugging and development.

In release mode all the references are combined in single style/script reference with query string looking something like:

/Scripts/assets.axd?js=jquery-1.4.1,main&cache=akqipjXPAq2UFLgARybjJ9QwjiA%3d

In this case client browser will do less web requests for the page and will receive all the static content in one go.

Client side cache

URL for assets has two parameters. File names and cache. Meaning of first one is obvious, but the second one is more interesting. It is SHA1 code of combined file contents of all assets that are included in this reference. So if you change any of that scripts this parameter will change. It gives us the ability to easily allow public caching of results for the reference meaning that even proxy servers will cache it. And the uniqueness of this URL will allow you to update files without asking users to press ctrl + f5 in order to get new version of content.

Server side cache

On server side two things are cached.

Minified js and css files. Its obvious that we shouldn’t minify files on each request, so its done once and placed in cache. Also each minified cache entry has a cache dependency on file system meaning that if you change file it will expire the cache. So you can modify static content just in production without any restrictions – new file will be delivered on next request.

Digital signature. signature is calculated once and is places in cache. It also has a dependency on files its signing. So if anything changes, signature will also change.

Unit tests

I’ve tried MSpec on this project as testing framework. And I really liked it. For me the main problem in tests was the test fixture setup. It was always bigger than action, code under test and results verification part.  But look at this test:

[Subject(typeof(AssetsHandler))]
public class When_compress_is_true_and_client_accepts_gzip : compression_spec
{
    Establish context = () => {
        Compress = true;
        AcceptEncoding = "gzip";
    };

    Because of = () => handler.ProcessRequest(httpContext.Object);

    It should_set_gzip_response_filter = () => 
        response.Filter.ShouldBeOfType<GZipStream>();

    It should_set_gzip_response_header = () => 
        responseMock.Verify(x => x.AppendHeader("Content-Encoding", "gzip"));
}

Its just great! All unnecessary code ceremony is moved to compression_spec class. In the test itself you see only required part.

Where to store script references before rendering?

In order to output all references at one go assets optimizer needs a place where to accumulate all required references. In ASP.NET its easy to implement because we have an AssetsManager control. During Init event it places this pointer into Page.Items state (before writing this manager, I didn’t know this state even exists Smile) and verifies that no other assets managers has placed themselves to this storage. Each proxy object in own event just finds that single manager in page state and registers all the styles and scripts there.

In ASP.NET MVC it’s a little bit more interesting. We don’t have manager there and need to find another state where to store references. The best place for the references I’ve found is HttpContext.Items. So each call to Assets.Script or Assets.Style just places a reference and renders nothing. And when Assets.Render() is called all the collected references are picked up from HttpContext. So if some of your scripts are not rendered, make sure that you register it before Render  method is called.

What next

What next I think would be useful:

  1. Components – ability to output assets in groups, not in one go
  2. Control over order – maybe automatic, maybe by providing some king of sort order property that developer could set
  3. Routing – nice url for handler

Jul 22, 2011

Slides and code

I promised to publish slides and code from my talk about unit testing. Here they are:

And a source code:

Jun 9, 2011

Getting started with NHibernate and ConfOrm (revamp)

I’m trying to post different things about NHibernate, but still post NHibernate for beginners is most popular. I wrote them in 2009 (Wow, how old I am! :D). First of all its in Russian and I think things have changed a bit since that time, mainly because of awesomeness of NuGet. This getting started will contain not only recommended mapping technique, but also references to some other useful things like GetHashCode, Equals implementations, transactions management, etc.

So lets get started. First of all install NuGet. Create a new empty MVC 3 project and add two class library projects name them %WhatYouLike%.Core and %WhatYouLike%.Data. First assembly will contain all business entities that NHibernate will save and load from data base. Data assembly is going to be used for NHibernate configuration, repositories, etc.

So when projects are created lets install NHibernate. In visual studio navigate to Tools –> Library Package Manager –> Package Manager Console. In the opened command prompt select your MVC project as default project and execute command: “Install-Package ConfOrm”. Do the same for Data project.

ConfOrm is an open source project that allows you to map all your domain model without any XML. I do use ConfOrm instead of Fluent NHibernate in this example just because first one is going to be added in core of NHibernate, so it is preferable (but of course not necessary) to get familiar with it.

Just can’t allow myself to forget about some political issues with ConfOrm and Fluent NHibernate :). ConfOrm project was started by Fabio Maulo who is lead of NHibernate project (correct me here if I’m wrong). And 3.2 version of NHibernate was released with mapping in code part that basically was very similar to ConfOrm way of doing things.

This fact has raised a little storm in twitter and James Gregory (author of Fluent NHibernate) wrote a blog post to explain what he thinks about it.

Some time later Fabio wrote a response post where he has shown how you can reuse your Fluent mappings with new API :).

So, don’t where it will end, but politics in open source space also takes place :). I recommend you to read mentioned two posts, just to be informed.

Now lets get back to our project. First thing we are going to do is add some entities to work with. NHibernate uses POCO objects. It means that you don’t need to inherit from base classes or implement some interfaces in order to create an entity that is going to be managed by NHibernate. Two things required:

  1. Entity should have public/protected default constructor (constructor with no parameters)
  2. All properties and methods should be virtual

So lets create some entities with associations and properties. Here is example domain model I’ve created:

domain model

Here is source code for one of the entities:

using System.Collections.Generic;

namespace nhrevamp.Core
{
    public class Post : Entity
    {
        public Post()
        {
            this.Comments = new HashSet<Comment>();
            this.Tags = new HashSet<Tag>();
        }

        public virtual string Title { get; set; }

        public virtual string Content { get; set; }

        public virtual ICollection<Comment> Comments { get; protected set; }

        public virtual ICollection<Tag> Tags { get; protected set; }
    }
}

All entities inherit from base class Entity with single property Id:

public abstract class Entity
{
    public virtual int Id { get; protected set; }
}

Notice that we are using ICollection from System.Collections.Generic not from Iesi.Collections. The reason for that is to keep our domain model as clean as possible. Also we initialize collections in constructor in order to avoid nasty NullReferenceException’s. And also we mark setters for collections as protected, just to avoid possibility to replace all collection with new one accidently.

So we have:

  1. One to many association (Post has many Comments)
  2. Many to one association (each Comment belongs to one Post)
  3. Many to many association (Post has many Tags and Tag has many Posts)

NHibernate has two main interfaces that you are going to work with. First is ISessionFactory. Instance of it should be used as a singleton and configured only once. This operation will take time, especially for complex domain models. The good news is that ISessionFactory is serializable and are able to cache it in order to not recreate it each time. Second interface is ISession. This one is used to query entities, update and delete them. Creation of ISession object is small, but you should consider some lifetime management issues with ISession. Here I’ve described how you can easily integrate it with MVC. 

In order to create ISessionFactory we need to configure it and provide mappings for our domain model. Lets start with configuration (you can read full list of available options here). Add new class to your .Data project, lets call it NHibernateConfigurator and create a single method there -BuildSessionFactory. Code there should be the following:

public class NHibernateConfigurator
{
    public ISessionFactory BuildSessionFactory()
    {
        var cfg = new Configuration();
        cfg.SessionFactory()
           .Proxy.Through<ProxyFactoryFactory>()
           .Integrate.Using<MsSql2008Dialect>()
           .Connected.ByAppConfing("connectionString");

        return cfg.BuildSessionFactory();
    }
}

So we say that we are going to work with SQL Server 2008 and connection string is placed in connection strings section of application settings file (web.config in our case).

This post is written for NHibernate 3.1 version. And this version has no default proxy factory with it. So you need to execute one more NuGet command for Data project: Install-Package NHibernate.LinFu. 3.2 version will be delivered with default proxy factory.

Now to the mappings. Its so easy, that you even wouldn’t believe:

public class DomainMapper
{
    public HbmMapping GenerateMappings()
    {
        IEnumerable<Type> domainEntities = GetDomainEntities();

        ObjectRelationalMapper relationalMapper = new ObjectRelationalMapper(); 
        relationalMapper.TablePerConcreteClass(domainEntities); // each concrete class should have its own table in DB
        relationalMapper.Patterns.PoidStrategies.Add(new NativePoidPattern()); // primary keys are generated by DB with identity field
        relationalMapper.Patterns.Sets.Add(new UseSetWhenGenericCollectionPattern()); // ICollection when met in classes should use Set in mappings
        relationalMapper.ManyToMany<Post, Tag>(); // Many to many association by some reasons cant be picked by ConfOrm. Need in set it manually
        relationalMapper.Cascade<Post, Tag>(Cascade.Persist); // when post is saved, tag also needs to be saved

        var patternsAppliers = new CoolPatternsAppliersHolder(relationalMapper); // this is set of column naming packs it used to get nice column names in FKs like PostId in Comments table
        patternsAppliers.Merge(new ClassPluralizedTableApplier(new EnglishInflector())); // means that Comment entity will have Comments table in DB
        Mapper mapper = new Mapper(relationalMapper, patternsAppliers);

        HbmMapping mapping = mapper.CompileMappingFor(domainEntities);
        File.WriteAllText(@"D:\mapping.xml", Serialize(mapping));

        return mapping;
    }

    private static IEnumerable<Type> GetDomainEntities()
    {
        Assembly domainAssembly = typeof(Entity).Assembly;
        IEnumerable<Type> domainEntities = from t in domainAssembly.GetTypes()
                                           where t.BaseType == typeof(Entity) && !t.IsGenericType
                                           select t;
        return domainEntities;
    }

    /// <summary>
    /// Generates XML string from <see cref="NHibernate"/> mappings. Used just to verify what was generated by ConfOrm to make sure everything is correct.
    /// </summary>
    protected static string Serialize(HbmMapping hbmElement)
    {
        var setting = new XmlWriterSettings { Indent = true };
        var serializer = new XmlSerializer(typeof(HbmMapping));
        using (var memStream = new MemoryStream())
        {
            using (var xmlWriter = XmlWriter.Create(memStream, setting))
            {
                serializer.Serialize(xmlWriter, hbmElement);
                memStream.Flush();
                byte[] streamContents = memStream.ToArray();

                string result = Encoding.UTF8.GetString(streamContents);
                return result;
            }
        }
    }
}

This code block contains one utility method called Serialize. It is used just to verify mappings. You can skip it. But its useful. That’s all. Some details I’ve added in comments. So now we are ready to start working with NHibernate.

Now we need provide generated mappings for our ISessionFactory. So add next two lines to the BuildSessionFactory method of NHibernateConfiguratorClass:

HbmMapping generateMappings = new DomainMapper().GenerateMappings();
cfg.AddDeserializedMapping(generateMappings, "domain");

Now we are ready to use NHibernate. First thing we need is actually DB schema. We can generate it from mappings with the help of SchemaExport class:

new SchemaExport(cfg).Execute(true, true, false);

This command is executed in NHibernateConfigurator class and creates all required tables for us:

Data base schema

In order to work properly NHibernate requires transactions to wrap all queries. I’ve described asp.net mvc integration in previous post. So I won’t describe it here.

The last thing you need to see here is a way to work with data. Here is how we can save new blog with post and some comments:

ISessionFactory sessionFactory = new NHibernateConfigurator().BuildSessionFactory();
using (ISession session = sessionFactory.OpenSession())
{
    using (ITransaction transaction = session.BeginTransaction())
    {
        Post post = new Post
                        {
                            Content = "test"
                        };
        post.Tags.Add(new Tag
                          {
                              Name = "test"
                          });
        post.Comments.Add(new Comment
                              {
                                  Author = "me",
                                  Content = "NH is awesome",
                                  Post = post
                              });
        session.SaveOrUpdate(post);
        transaction.Commit();
    }
}

Notice that we save only Post object, all associations are going to be saved by cascade. Generated SQL is straight forward:

begin transaction with isolation level: Unspecified

INSERT INTO Posts
           (Title, Content)
VALUES     (NULL /* @p0 */,
            'test' /* @p1 */)
select SCOPE_IDENTITY()

INSERT INTO Comments
           (Author, Content, PostId)
VALUES     ('me' /* @p0 */,
            'NH is awesome' /* @p1 */,
            1 /* @p2 */)
select SCOPE_IDENTITY()

INSERT INTO Tags
           (Name)
VALUES     ('test' /* @p0 */)

select SCOPE_IDENTITY()

INSERT INTO PostToTag
           (PostId,
            TagId)
VALUES     (1 /* @p0 */,
            1 /* @p1 */)
commit transaction

NHibernate has mature Querying API that was improved in 3.0 version. Also it has LINQ implemented with session.Query<T> extension method. This post has no intention do describe them.

So you are almost NHibernate Guru already ;). What to read next:

  • Overriding GetHashCode and Equals methods for your domain entities (link)
  • Primary keys generations and consequences of using them (link)
  • Lazy, eager loading (link) and select N+1 problem (link)
  • Transactions and Sessions lifetime management (link)
  • Inverse attribute for mapping collections (link)

Happy NHibernating!

Apr 12, 2011

Unit testing classes with a lot of dependencies

I’m sure every TD developer will scream that it’s not right to have classes with a lot of dependencies. I agree with you, but it happens. It happens for example in MVP pattern for ASP.NET, or for controllers in MVC.

Why it happens? The main reason I think are unnecessary abstractions. Many applications have interface like IRepository<T> : where T : IEntity. Such interface seams to be very useful. It gives you strongly typed access to the entities, and gives you ability to put common methods there (like Get<T>(int id)). Everything looks good so far. We configure our application to use IoC container and don’t bother with dependencies:

public ProductsController : Controller
{
    private readonly IRepository<Product> productsRepository;

    public ProductsController(IRepository<Product> productsRepository)
    {
        this.productsRepository = productsRepository;
    }

    public ActionResult Index()
    {
        var products = productsRepository.GetAll();
        return View(products);
    }
}

Everything looks good so far and we are able to write very simple unit test for it. Its easy to mock GetAll() method and verify that View.Model contains exact the same collection that returned from repository.

But then you need to create a Create method that requires getting list of all categories that could be assigned to product. And all of a sudden you have two dependencies:

public ProductsController : Controller
{
    private readonly IRepository<Product> productsRepository;
    private readonly IRepository<Category> categoriesRepository;

    public ProductsController(IRepository<Product> productsRepository, IRepository<Category> categoriesRepository)
    {
        this.productsRepository = productsRepository;
        this.categoriesRepository = categoriesRepository;
    }

    public ActionResult Index()
    {
        var products = productsRepository.GetAll();
        return View(products);
    }

    public ActionResult Create()
    {
        var categories = categoriesRepository.GetAll();
        ViewBag.Categories = categories;
        return View();
    }
}

Its still looking good. But only if you have 2-3 tests that are using ProductsController constructor with 1 parameter. When you have 20 of those its becoming a nightmare to add new dependency in constructor.

I do understand that its not best example of why a lot of dependencies happens, but its real one. Its very easy to have up to 4-6 decencies in constructor. And to do with it in tests? Each test needs to set 2 or 3 of them and he doesn’t cares about other. My first approach was creating a helper methods as such:

public ProductsController GetController(IRepository<Product> productsRepository)
{
    return new ProductsController(productsRepository, Mock.Of<IRepository<Category>>);
}

Its perfectly works for classes with less then 3 dependencies. But even there the problem still exists. Consider mocking of current HttpContext.Current.User.Identity. It may happen that each controller action needs access to it, but most of tests doesn’t care what is going to be returned as current user. You will need to copy paste mocking code in each of such methods, or put some complex chain of methods calling each other to get default user for all test controllers.

What I prefer to do now is having a simple factory for controllers (presenters) in test class:

internal class ProductsControllerFactory()
{
    public ProductsControllerFactory()
    {
        this.CategoriesRepsitory = Mock.Of<IRepository<Category>>();
        this.ProductsRepository = Mock.Of<IRepository<Product>>();
        
        // you can put all default stubs here
    }

    public ProductsController GetController()
    {
        return new ProductsController(this.CategoriesRepository, 
                                      this.ProductsRepository);
    }

    public IRepository<Category> CategoriesRepsitory { get; set; }

    public IRepository<Product> ProductsRepository { get; set; }
}

So you end up with having constructor call in one place. Adding a dependency won’t affect existing tests, it will affect only controller factory. Each test can easily set dependency it needs and ignore dependencies it doesn’t cares about.

Apr 9, 2011

Lightweight NHibernate and ASP.NET MVC integration with Autofac

Many times when new project stars and we want to use NHibernate relatively a lot of work need to be done. Among them are:

  • Mapping of entities (I prefer automapping)
  • ISessionFactory singleton
  • ISession lifetime management (Per web request)
  • Transaction management

Sharp architecture project has all of them done and ready to use. But as for me this project has become too big and hard to understand. I wanted to have full control on what is happening in my app and didn’t want to have such a lot of abstractions. For example Repository and Entity objects that have inheritance chain about to 5 or 6 objects.

So I decided to show how very simple integration can be made with a minimum amount of code. To get all mentioned libraries I will use NuGet. We will need:

  • NHibernate
  • Fluent NHibernate
  • Autofac
  • Autofac.Mvc3

Lets start with mapping / session factory configuration:

public Configuration Configure()
{
    var configuration = new Configuration();
    configuration.SessionFactory()
                 .Proxy.Through<ProxyFactoryFactory>()
                 .Integrate.Using<MsSql2005Dialect>()
                 .Connected.ByAppConfing("dbConnection");


    FluentConfiguration fluentConfiguration = Fluently.Configure(configuration);
    fluentConfiguration.Mappings(map => map.AutoMappings.Add(
                                            new ModelGenerator().Generate()));

    return fluentConfiguration.BuildConfiguration();
}

public ISessionFactory GetSessionFactory()
{
    var configuration = Configure(); 
    return configuration.BuildSessionFactory();
}

Few things to note here. Combination of Loquacious and Fluent configuration is used because first one is supporting all NHibernate features, second one handles mappings integration. Also Model generator class is used:

private class ModelGenerator
{
    public AutoPersistenceModel Generate()
    {
        AutoPersistenceModel automap = new AutoPersistenceModel();

        automap.Conventions.AddFromAssemblyOf<ModelGenerator>();
        automap.UseOverridesFromAssemblyOf<ModelGenerator>();
        automap.AddEntityAssembly(Assembly.GetAssembly(typeof (Entity)))
            .Where(objectType => objectType.IsSubclassOf(typeof(Entity)));

        return automap;
    }
}

Here we setup location for the conventions, overriding's and entities. All classes that are inherited from Entity will be mapped. For conventions I’m using sharp architecture’s with small tweaks to have nice constraints names when generating schema from mappings:

public class ReferenceConvention : IReferenceConvention
{
    public void Apply(FluentNHibernate.Conventions.Instances.IManyToOneInstance instance)
    {
        string fkName = string.Format("{0}_{1}_FK", 
                                      instance.Name, instance.EntityType.Name);
        instance.ForeignKey(fkName);

        instance.Column(instance.Property.Name + "Fk");
    }
}

public class HasManyToManyConvention : IHasManyToManyConvention
{
    public void Apply(IManyToManyCollectionInstance instance)
    {
        string fkName = string.Format("{0}_{1}_FK", 
                                      instance.Member.Name, instance.EntityType.Name);
        instance.Key.ForeignKey(fkName);

        instance.Cascade.SaveUpdate();
    }
}

Now to the web part. In global asax on Application_Start event we need to setup Autofac and change the default controllers factory. To do this:

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetAssembly(typeof (AuthorizationController)));
builder.Register(x => new NHibernateConfigurator().GetSessionFactory())
    .SingleInstance();
builder.Register(x => x.Resolve<ISessionFactory>().OpenSession())
    .InstancePerHttpRequest();

builder.RegisterModule(new AutofacWebTypesModule());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Code here is pretty clear. We setup ISessionFactory to be singleton, ISession instance is resolved by container and has PerHttpRequest lifestyle. Notice call of builder.RegisterModule that is going to add all the required http modules to support per web request lifestyle and change default controller factory to the one that uses Autofac. So now we are able to write code like this:

public class AuthorizationController : Controller
{
      private ISession session;

      public AuthorizationController(ISession session)
      {
          this.session = session;
      }

      public ActionResult Index()
      {
          var users = this.session.QueryOver<User>().List();
          return View(users);
      }
}

So we have controller that depends on ISession, which depends on ISessionFactory, which depends on our Nhibernate configurator class. Isn’t it kind from Autofac to handle all this? Smile

One last but important thing we need to do. Each call to the data base should be wrapped to correct transaction. You can read here why. The easiest way to handle this is to create action filter:

public class TransactionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        DependencyResolver.Current.GetService<ISession>().BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        ITransaction currentTransaction = DependencyResolver.Current.GetService<ISession>().Transaction;

        if (currentTransaction.IsActive)
        {
            if (filterContext.Exception != null && filterContext.ExceptionHandled)
            {
                currentTransaction.Rollback();
            }
        }
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        ITransaction currentTransaction = DependencyResolver.Current.GetService<ISession>().Transaction;

        base.OnResultExecuted(filterContext);
        try
        {
            if (currentTransaction.IsActive)
            {
                if (filterContext.Exception != null && !filterContext.ExceptionHandled)
                {
                    currentTransaction.Rollback();
                }
                else
                {
                    currentTransaction.Commit();
                }
            }
        }
        finally
        {
            currentTransaction.Dispose();
        }
    }
}

Original implementation is taken from Sharp architecture and small changes made due to Autofac. So now out Index method should be marked with transaction attribute:

[Transaction]
public ActionResult Index()
{
    return View();
}

That's probably all we need to have NHibernate. As always source code is attached:

Jan 6, 2011

Episerver CMS 6 search

Had to make some additional staff in EPiServer search functionality. I had to add ability to filter pages by category, page type, and keyword in content. Firstly I have tried to do it with DataFactory.Instance.FindPagesWithCriteria method. But the thing is that I couldn’t  find a way to filter data by search keyword.

I knew that SearchDataSource does this somehow and wanted to reuse that logic. But when I looked at it in reflector, I found a method 100 lines long doing some really fancy staff to make select by keywords. So the best way to make search that I need is to do it through SearchDataSource.

Fortunately it provides public property called Criteria. It is a criteria that are going to be passed for underlying DataFactory.FindPagesWithCriteria call.

So the search that I needed could be implemented in the this way. Aspx part:

<EPiServer:SearchDataSource ID="uiSearchDataSource" runat="server" EnableVisibleInMenu="false"
                            PageLink="<%# PageReference.StartPage %>">
    <SelectParameters>
        <asp:QueryStringParameter Name="SearchQuery" QueryStringField="search" DefaultValue="" />
    </SelectParameters>
</EPiServer:SearchDataSource>

And in code behind:

var pageTypeCategory = new PropertyCriteriaControl(new PropertyCriteria
                            {
                                Condition = CompareCondition.Equal,
                                Name = "PageTypeID",
                                Type = PropertyDataType.PageType,
                                Value = PageType.Load("Article").ID.ToString(),
                                Required = true
                            });

var pageTypeCategory1 = new PropertyCriteriaControl(new PropertyCriteria
                            {
                                Condition = CompareCondition.Equal,
                                Name = "PageCategory",
                                Type = PropertyDataType.Category,
                                Value = Category.Find("category2").ID.ToString(),
                                Required = true
                            });

this.uiSearchDataSource.Criteria.Add(pageTypeCategory);
this.uiSearchDataSource.Criteria.Add(pageTypeCategory1);

Note that Name property of each criteria should be as shown in code above, otherwise it won’t work. Hope it helps someone!