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";
scope.Commit();
}



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.

Friday, April 09, 2010

NCommon Setup

Today I finally get to a post my friend Dan has been riding me to do for some time. How to setup NCommon and StructureMap with Asp.Net MVC.

Before I get started I want to talk a little about what NCommon is. Simply put, NCommon is a library of commonly used design patterns when developing applications. I took that right from the project website. It was developed by Ritesh Rao. The code can be found at google code. The patterns it implements are as follows...
  1. Unit of Work
  2. Repository using Linq
  3. Validation and business rules
  4. Specification using expressions
  5. Guard class
  6. Utility class
This post wont talk to much about these patterns but future posts will talk about some of them.

So Lets get started.

I will be focusing on the following versions...
ASP.Net MVC version 1.0
StructureMap version 2.5.3
StructureMap Adapter version 1.0
NCommon version 1.0

I plan on updating all version once VS2010 comes out. So there will possibly some differences with the setup if running a later version of ASP.Net MVC.

So my project uses Linq 2 Sql as the backend interface to the database, I could have went with Entity Framework or NHibernate as well since NCommon also supports those as well. While I am at it I did not have to use StructureMap either I could have went with Windsow or Spring or Unity. I just chose StructureMap since I like it best. In the future I might switch to EF 4 or NHibernate with fluent NH but for now I am sticking to Linq 2SQL and StructureMap.

So the first thing you need to do is set up you StructureMap Container and store it in the NCommon.Storage.Store.

In the container setup you need to register some things.


public static Container BuildContainer()
{
Container container = new Container(x =>
{
//ncommon
x.ForRequestedType().CacheBy(InstanceScope.Hybrid).TheDefaultIsConcreteType();
x.ForRequestedType(typeof(IRepository<>)).CacheBy(InstanceScope.Hybrid).TheDefaultIsConcreteType(typeof(LinqToSqlRepository<>));
x.ForRequestedType().CacheBy(InstanceScope.Hybrid).TheDefault.Is.ConstructedBy(
() => new DataModelDataContext(ConfigurationManager.ConnectionStrings["ConnectionStringNameFromWeb.Config"].ConnectionString));


//Other project items here.....
});

container.AssertConfigurationIsValid();
return container;
}


So what is going on here... We create a new StructureMap container and tell it how to create objects when asked for a certain object. the first line we tell the container when asked for IUnitOfWorkFactory we want it to return LinqToSqlUnitOfWorkFactory since I am using Linq2Sql. If I was using EF I would have set it up to return EFUnitOfWorkFactory. The same goes for typeof(Irepository<>) we have it return typeof(LinqToSqlRepository). Finally we tell the container how to create our DataContext.

So How do we call this method. Well in the global.asax.cs file is how.

protected void Application_Start()
{
ConfigureContainer();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new IocControllerFactory());
LinqToSqlUnitOfWorkFactory.SetDataContextProvider(GetDataContext);
}

private void ConfigureContainer()
{
Container container = StructureMapBootStrapper.BuildContainer();

Store.Application.Set("ApplicationContainer", container);

ServiceLocator.SetLocatorProvider
(
() => new StructureMapServiceLocator(Store.Application.Get ("ApplicationContainer"))
);

}


So as you can see on the app startup we call ConfigureContainer and that method calls our build container and then sets the container on the Store. We then use the ServiceLocator and tell it how to find our newly created container. BTW.... the Service locator is part of the Common Service Locator Library from Microsoft using the StructureMap Adapter.

The Next important thing we need to do is tell MVC how to inject our controllers. If you see in the code above ControllerBuilder.Current.SetControllerFactory(new IocControllerFactory()); This code tells MVC to use a ControllerFactory I created instead of the default. Note the following code will not work in MVC 2.0.


public class IocControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
IController result = null;
if (controllerType != null)
{
try
{
IContainer container = Store.Application.Get("ApplicationContainer");
result = container.GetInstance(controllerType) as Controller;

//result = ObjectFactory.GetInstance(controllerType) as Controller;
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;

}
}

return result;
}
}


As you can see what we are doing is we are asking the Store for our container and trying to find the requested controller. StructurMap is smart in that if we did not define it in the registry it will try to create it itself using the greasiest constructor.

Finally the last thing we need to set the DataContext on the LinqToSqlUnitOfWorkFactory. again from teh app startup method in the global.asax.cs file we do this LinqToSqlUnitOfWorkFactory.SetDataContextProvider(GetDataContext); where GetDataContext is a property that looks like this


private DataContext GetDataContext()
{
return (DataContext)Store.Application.Get("ApplicationContainer").GetInstance(typeof (DataContext));
}


All it does is ask the store for our container and ask it for the DataContext.

That was how I set up my application to use NCommon. In the next post I will talk more about NCommon and some of the patterns. Stay tuned.