Wednesday, April 28, 2010

NCommon Repository, and Unit of Work

This will continue my talks on NCommon.

One reason I like NCommon is it implements some patterns I like. One of my favorite patterns is Unit of Work.

From Martin Fowler:
A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

So lets say you want to insert/update/delete a person and that persons address in your model. The pattern will basically wrap all the database operations into one transaction automatically for you.

NCommon implements Unit of Work for use again with the three provided ORMs (Linq 2 SQL, NHibernate, and EF). To use it your code is simple basiclly it will look something like this...

using (var scope = new UnitOfWorkScope())
//Your real work here
Person p = GetPerson(1);
p.FirstName = "Bob";
p.Address.State = "WI";

What this will do will wrap the person update and the Address update into one transaction and execute them both. If one fails both are rolled back. You get all of that free of charge so to speak. NOTE: Nothing is free in this world, but what is meant is just by using the using statement for unit of work, I get all of the goodies of transactions and model change discovery.

Another pattern I am trying to use more is the Repository patter. Again from Martin Fowler:
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

So what is accomplished with repository is you abstract out the database code. what I mean is your model queries the repository in a way that is understandable and the repository handles the query. The repository handles the calls to whatever system is being used for persistence, be is SQL Server, Oracle, FlatFile, or whatever. NCommon doesn't exactly hide the ORM from the model since you need to use one of the three Repository classes, but it is simple enough to abstract this away with your own domain specific wrappers.

I was going to show some code on how to use the repository , but since it really is pretty simple, I will leave it out. If you are interested download the NCommon code and take a look in the unit tests. There you will see a very basic example on how to use them. I might do a follow up post with how I implemented my repositories with NCommon as well.

I am not sure if I will go into any more detail about the other pieces of NCommon (BusinessRules /Validation, Specifications, Guard, or Store) I do use some of them, and find them useful, but think there are also many good ways to solve the problems they address. If you would like more please let me know and maybe I could whip something up.
Post a Comment