Sunday, 21 April 2013

Introduction to TinyNH, A Simple NHibernate Infrastructure

TinyNH is a demo project and series of articles designed to help you get your project up and running with a simple solid NHibernate persistence infrastructure. See contents for a full list of articles.

It isn't a framework, it's more like a template project that demonstrates some key infrastructural elements that you're likely to need. Each element is accompanied by an article (on this blog) that describes what it does and why, helps you to decide whether or not you need it and, if so, tells you how to add it to your project.

Why?

You’re working on your latest project and, believe it or not, you have a few things stored in a relational database that your users need to view, edit and save. You’re weighing up the options available for handling data access.

You briefly consider hand-coding a data access layer using raw ADO.Net. Although there are some advantages to keeping things really simple, it’s hard to justify this approach, given your experience with practices and frameworks that will get the job done a lot quicker.

You then look at micro ORMs, like Dapper.Net and Massive, which offer a lightweight, efficient and fast mechanism for mapping database records to objects (nice overview here). Dapper Extensions even adds support for inserts and updates. However, your project has a reasonably complex object model. It’s small, but it’s a real domain model nevertheless, with a few associations between objects and a collection or two. Dapper.Net would do the work of generating the inserts and updates, but you’d have to write some fairly fiddly code to ensure that parents, child objects and items in collection were saved in the correct order.

You really want a solution that can handle the complexity of efficiently loading and saving a graph of connected objects. Which leads you to a full-featured ORM, such as Entity Framework or NHibernate.

NHibernate is your weapon of choice when it comes to full-on ORM action. A quick “install-package NHibernate” and you have NHibernate referenced, but what next? You realise that, in addition to your object mappings, you have a fair bit of infrastructure code to write to get things up and running, things like:
  • Initialising the configuration
  • Setting up the configuration and session factory in a thread-safe manner
  • Testing your configuration and mappings
  • Managing sessions and transactions
Using NHibernate to manage a handful of classes is starting to feel like a bigger step than it should. Many projects you've worked on have accreted layers of abstraction and other infrastructure around NHibernate that seems over-the-top for a simpler model. You’re determined to keep things simple and start picking out the bare minimum you need for your project, assembling pieces from various projects, documentation and blog articles. You feel like you're having to think a little harder about this than you should...

Meanwhile, another team is asking for your advice in a similar scenario. They're familiar with NHibernate, but, given that you're having a "where do I start" moment yourself, you know that they'd benefit from a coherent end-to-end guide to getting their project up and running.

Overview

The "you" above was me. What I have tried to do with TinyNH is to identify the core infrastructural elements that you need when working with NHibernate and distil this into several small (tiny!) pieces of infrastructure code that you can add directly to your project. This includes:
  • Model - Creating your domain model
  • Configuration - A flexible approach to NHibernate configuration and mapping
  • Start-up - A mechanism to ensure thread-safe NHibernate initialisation
  • Context sessions - Efficient NHibernate session management in a web application
  • Automated Testing - Test your database without hitting F5!
  • Developer friendly database set up - Automated local database set up for each developer.
TinyNH is not a library or framework. It is a guidance project that provides a demo of some infrastructure code that you’ll need to add to your own solution using some traditional copying and pasting. 

Keeping Things Simple

NHibernate and Entity Framework have a reputation for being "overly complex" or "heavy and complicated". There is a feeling that the investment required to work effectively with an ORM might not pay off on simpler projects.

The development of TinyNH was motivated by the belief that a full-blown ORM can be used successfully on simpler projects. The code used to manage NHibernate is pretty small and easy to follow. It includes a 49-line class to create our configuration, a 53-line class to manage NHibernate start-up, a couple of 50-60 line classes to manage sessions in web applications and a 75-line entity base class. These numbers include comments and whitespace etc, the number of logical lines of code is probably around 30-40% of the above.

Has the "it's too complicated" viewpoint been partly reinforced by experiences with overly complex abstractions around NHibernate in "enterprisey" solutions? TinyNH is based on the opinion that you do not, by default, need to "hide" NHibernate with things like UnitOfWork and IRepository abstractions. Experienced NHibernate and TDD experts can make informed decisions about where persistence ignorance might genuinely benefit their solution and add a lightweight layer over the top of TinyNH if they need it.

Let's not pretend that there aren't gotchas, limitations and best-practices that take time to learn when working with an ORM. TinyNH offers less experienced NHibernate users a short cut to getting their project up and running with the essential pieces in place, allowing them to focus on the underlying mechanics of the framework.

What Next?

Read getting started to find out how to run the TinyNH project, then work your way through the articles, starting from the contents page.

I hope that TinyNH becomes a useful resource for both new and experienced NHibernate users.



No comments:

Post a Comment