NHibernate and the Unit of Work pattern (Part 3)

Introduction

In the previous two posts which you can find here and here I introduced the Unit of Work pattern and developed a working version based on NHibernate. One weak point of the shown implementation is that it is strictly non thread safe. In NHibernate the session object takes the role of the Unit of Work container. The session object is not thread safe! That is a session instance may not be accessed from different threads. If your application is running on multiple threads (typically an application running on the server) then you have to open a new session instance for each running thread.

In this post I want to improve the implementation of the Unit of Work pattern such as that it is thread safe. The class which starts a new unit of work is a static class. All static members of this class are accessible from each thread of the application domain in which your application is running. Now fortunately .NET provides us a mean to define pseudo static fields in a type which are local to a single thread. That is this state is not shared between different threads. Each thread has its own thread static state. To make a field thread static one has to decorate it with the [ThreadStatic] attribute.

The easiest and most pragmatic approach would now be to just decorate our _innerUnitOfWork field of the UnitOfWork class with the [ThreadStatic] attribute. But eventually we want to keep additional state in our Unit of Work. Thus we implement a special Data class which is a kind of a wrapper around a Hashtable.

Container for Thread Static State

There are 2 possible scenarios I want to discuss. You either develop an application with a web client or an application with a windows client (e.g. WinForms).

In a web application one has the so called Http context for each request. Multiple requests from different clients can run at the same but each of them runs on a different thread and has it's own context. In this situation we store the data relevant to the unit of work in the context of the request.

In a windows client application (i.e. Smart Client Application) on the other hand we have a single client that might run on different threads at the same time. In this situation we "attach" the data relevant to the unit of work in so called thread-static fields. A thread-static field is not shared between different threads in the same application. To make a (static) field thread-static we have to just decorate it with a [ThreadStatic] attribute.

In our Unit of Work implementation we have the static UnitOfWork class which contains a static field _innerUnitOfWork of type IUnitOfWork. We now need to change this since this kind of implementation is not thread safe. Since we might want to save other data in a thread safe way as well (not just the current instance of the unit of work) we choose a slightly more sophisticated solution.

Let's define a static class Local which encapsulates the details whether we run a web- or a win-application. This class has just one (static) read-only property Data of type ILocalData.

using System;
using System.Collections;
 
namespace NHibernateUnitOfWork
{
    public static class Local
    {
        static readonly ILocalData _data = new LocalData();
 
        public static ILocalData Data
        {
            get { return _data; }
        }
 
        private class LocalData : ILocalData
        {
            // implementation details to de defined
        }
    }
}

All details of our implementation are now "hidden" in the class LocalData which we choose to be a private child class of the Local class. We now want to be able to save into and read data from this local container via a key, e.g.

Local.Data["some key"] = someValue;
// or
otherValue = Local.Data["other key"];

This should be in a thread safe way. Obviously the above sample client code implies that we use some kind of dictionary to internally store our data.

As usual we formulate our intention in a unit test which might look like this

using System;
using NUnit.Framework;
 
namespace NHibernateUnitOfWork.Tests
{
    [TestFixture]
    public class LocalData_Fixture
    {
        [Test]
        public void Can_store_values_in_local_data()
        {
            Local.Data["one"] = "This is a string";
            Local.Data["two"] = 99.9m;
            var person = new Person {Name = "John Doe", Birthdate = new DateTime(1991, 1, 15)};
            Local.Data[1] = person;
 
            Assert.AreEqual(3, Local.Data.Count);
            Assert.AreEqual("This is a string", Local.Data["one"]);
            Assert.AreEqual(99.9m, Local.Data["two"]);
            Assert.AreSame(person, Local.Data[1]);
        }
    }
}

The test shows that I want to be able to not only store basic types but any complex type in my local data container. In this case a string, an integer and an instance of a Person class. The Person class is very basic at looks like follows

public class Person
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual DateTime Birthdate { get; set; }
}

Please also note that I use keys of different type (string and int).

Implementation for Smart Client Applications

Let's first assume that we want to provide a thread safe unit of work implementation for the smart client application. Then the most basic implementation to fulfill  this test is

private class LocalData : ILocalData
{
    private static Hashtable _localData = new Hashtable();
 
    public object this[object key]
    {
        get { return _localData[key]; }
        set { _localData[key] = value; }
    }
 
    public int Count
    {
        get { return _localData.Count; }
    }
}

I just take a hash table as local storage and define an indexer property and a Count property (Note: a HashTable is an often used implementation of a Dictionary).

We want to also be able to clear the content of the local store and thus we define the following test

[Test]
public void Can_clear_local_data()
{
    Local.Data["one"] = "This is a string";
    Local.Data["two"] = 99.9m;
    Assert.AreEqual(2, Local.Data.Count);
    Local.Data.Clear();
    Assert.AreEqual(0, Local.Data.Count);
}

The code to fulfill this test is trivial, just add the code snippet below to the LocalData class

public void Clear()
{
    _localData.Clear();
}

Unfortunately the test still faults when run! This is because the local data storage is static and all test methods access the same container we have a "side effect" which we must now compensate. We can do it by just clearing the local data container before each test. Add this code to the test fixture class to compensate the side effect

[SetUp]
public void SetupContext()
{
    Local.Data.Clear();     // start side-effect free!
}

Re-run all tests. They should now all pass...

And now comes the "tricky" part of the implementation where we want to guarantee that our local data store is indeed thread safe. Let's first define a test for this scenario

private ManualResetEvent _event;
 
[Test]
public void Local_data_is_thread_local()
{
    Console.WriteLine("Starting in main thread {0}", Thread.CurrentThread.ManagedThreadId);
    Local.Data["one"] = "This is a string";
    Assert.AreEqual(1, Local.Data.Count);
 
    _event = new ManualResetEvent(false);
    var backgroundThread = new Thread(RunInOtherThread);
    backgroundThread.Start();
 
    // give the background thread some time to do its job
    Thread.Sleep(100);
    // we still have only one entry (in this thread)
    Assert.AreEqual(1, Local.Data.Count);
 
    Console.WriteLine("Signaling background thread from main thread {0}", Thread.CurrentThread.ManagedThreadId);
    _event.Set();
    backgroundThread.Join();
}
 
private void RunInOtherThread()
{
    Console.WriteLine("Starting (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
    // initially the local data must be empty for this NEW thread!
    Assert.AreEqual(0, Local.Data.Count);
    Local.Data["one"] = "This is another string";
    Assert.AreEqual(1, Local.Data.Count);
 
    Console.WriteLine("Waiting on (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
    _event.WaitOne();
    Console.WriteLine("Ending (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
}

In the above code I run two threads in parallel, the thread on which the test is running (let's call it the main thread) and an additional background thread. The code which is executed in the background thread is implemented in the helper method RunInOtherThread. To be able to synchronize the two threads I use an Event, in this case a ManualResetEvent. I have put some Console.WriteLine statements in the code for debugging purposes.

In the main thread I add some data to the local data store. Then I spin up the background thread. In the background thread I first test that my (thread-) local data store is empty and then also fill in some data. With the Assert statements I test that we really have a thread safe behavior.

The only change needed to make my implementation thread safe is to decorate the static field _localData with the [ThreadStatic] attribute.

[ThreadStatic]
private static Hashtable _localData = new Hashtable();

When the test is run it should pass and produce an output similar to this

image

Implementation for Web

As mentioned above in this scenario we want to store our local data in the context of the current HTTP request.

First I want to provide an indicator whether I am running in web and thus I add the following to the code snippet to the LocalData class

public static bool RunningInWeb
{
    get { return HttpContext.Current != null; }
}

Here I use the HttpContext class of the .NET framework (namespace System.Web). It's static property Current is equal to null if we do not run in the context of a web application.

To abstract the details of the context (web- or smart client application) I define a private read-only property LocalHashtable as below

private static readonly object LocalDataHashtableKey = new object();
 
private static Hashtable LocalHashtable
{
    get 
    {
        if (!RunningInWeb)
        {
            if (_localData == null)
                _localData = new Hashtable();
            return _localData;
        }
        else
        {
            var web_hashtable = HttpContext.Current.Items[LocalDataHashtableKey] as Hashtable;
            if (web_hashtable == null)
            {
                web_hashtable = new Hashtable();
                HttpContext.Current.Items[LocalDataHashtableKey] = web_hashtable;
            }
            return web_hashtable;
        }
    }
}

In this code I use the RunningInWeb helper method to distinguish the two cases. In the case of NOT running in web context I test whether my thread static _localData field is equal to null, and If so I initialize it with a new instance of type Hashtable. I then return this instance. On the other hand, when running in web context I try to access a hash table instance in the Items collection of the current Http context. If I do not find such an instance then I create a new one and put it into the items collection of the current context. I then return the instance.

Now I have to locate every place in the LocalData class where I access the _localData field directly and replace it with a reference to the LocalHashtable property. E.g. the indexer will have to be changed as follows

public object this[object key]
{
    get { return LocalHashtable[key]; }
    set { LocalHashtable[key] = value; }
}

Our thread- and/or Http context local data store is now complete and we can use it in our UnitOfWork class.

Make Unit Of Work implementation thread safe

To make our unit of work implementation thread safe we change the implementation of our static UnitOfWork class as shown below

public static class UnitOfWork
{
    private static readonly IUnitOfWorkFactory _unitOfWorkFactory = new UnitOfWorkFactory();
 
    public static Configuration Configuration
    {
        get { return _unitOfWorkFactory.Configuration; }
    }
 
    public const string CurrentUnitOfWorkKey = "CurrentUnitOfWork.Key";
 
    private static IUnitOfWork CurrentUnitOfWork
    {
        get { return Local.Data[CurrentUnitOfWorkKey] as IUnitOfWork; }
        set { Local.Data[CurrentUnitOfWorkKey] = value; }
    }
 
    public static IUnitOfWork Current
    {
        get
        {
            var unitOfWork = CurrentUnitOfWork;
            if (unitOfWork == null)
                throw new InvalidOperationException("You are not in a unit of work");
            return unitOfWork;
        }
    }
 
    public static bool IsStarted
    {
        get { return CurrentUnitOfWork != null; }
    }
 
    public static ISession CurrentSession
    {
        get { return _unitOfWorkFactory.CurrentSession; }
        internal set { _unitOfWorkFactory.CurrentSession = value; }
    }
 
    public static IUnitOfWork Start()
    {
        if (CurrentUnitOfWork != null)
            throw new InvalidOperationException("You cannot start more than one unit of work at the same time.");
        
        var unitOfWork = _unitOfWorkFactory.Create();
        CurrentUnitOfWork = unitOfWork;
        return unitOfWork;
    }
 
    public static void DisposeUnitOfWork(IUnitOfWorkImplementor unitOfWork)
    {
        CurrentUnitOfWork = null;
    }
}

As you can see the field _innerUnitOfWork has gone and is replaced by a private property CurrentUnitOfWork. This property in turn uses the previously defined Local class to store the current unit of work item.

Note that there is one place in our unit tests that makes a reference to the field _innerUnitOfWork and must thus be changed. It's the method ResetUnitOfWork in the class UnitOfWork_With_Factory_Fixture. The new implementation is

private void ResetUnitOfWork()
{
    // assert that the UnitOfWork is reset
    var propertyInfo = typeof(UnitOfWork).GetProperty("CurrentUnitOfWork",
                        BindingFlags.Static | BindingFlags.SetProperty | BindingFlags.NonPublic);
    propertyInfo.SetValue(null, null, null);
}

When run, all tests should again pass. So now our implementation of the unit of work is thread safe.

You can find the full code here.

Enjoy

Blog Signature Gabriel .

Print | posted on Saturday, April 26, 2008 7:04 AM

Comments on this post

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
I can't access the code using tortoisesvn, weird.

Error: REPORT request failed on '/svn/!svn/vcc/default'

Error: REPORT of '/svn/!svn/vcc/default': 400 Bad Request (http://hibernatingrhinos.googlecode.com)

Any help?
Left by Chua Wen Ching on Apr 26, 2008 8:32 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Create a new folder. Right click and choose "SVN chekcout...". Enter the URL http://hibernatingrhinos.googlecode.com/svn/trunk/UnitOfWork/" and press ok
with me it works (I just tried it to be shure)
Left by Gabriel Schenker on Apr 27, 2008 7:10 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Ya I tried that yesterday and 1 minute ago ... it didn't work ...

Am I the only one facing this problem? Weird ...
Left by Chua Wen Ching on Apr 27, 2008 2:09 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
@Chua: what SVN client do you have? I use TortoiseSVN. I never had problems so far with it.
Left by Gabriel Schenker on Apr 28, 2008 9:56 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
I don't think the Configuration creation is thread safe. The following test fails every time (the configuration seems to get in a right state and fails in different ways):


private Configuration _configuration1;
private Configuration _configuration2;

[Test]
public void Configuration_creation_is_thread_safe()
{
Console.WriteLine("Getting configuration in main thread {0}", Thread.CurrentThread.ManagedThreadId);
var backgroundThread = new Thread(RunInOtherThread);
backgroundThread.Start();
_configuration1 = _factory.Configuration;
Console.WriteLine("Got configuration in main thread {0}", Thread.CurrentThread.ManagedThreadId);
backgroundThread.Join();
Console.WriteLine("Configuration 1 hashcode {0}, configuration 2 hashcode {1}", _configuration1.GetHashCode(), _configuration2.GetHashCode());
Assert.IsTrue(object.ReferenceEquals(_configuration1, _configuration2));
}



private void RunInOtherThread()
{
Console.WriteLine("Getting configuration in background thread {0}", Thread.CurrentThread.ManagedThreadId);
_configuration2 = _factory.Configuration;
Console.WriteLine("Got configuration in background thread {0}", Thread.CurrentThread.ManagedThreadId);
}


Adding some double checked locking around the initialisation makes it thread safe:


public Configuration Configuration
{
get
{
if (_configuration == null)
{
lock (_initLock)
{
InitConfiguration();
}
}
return _configuration;
}
}

private void InitConfiguration()
{
if (_configuration == null)
{
_configuration = new Configuration();
... etc ...

}
}
}

Left by Dan on May 21, 2008 7:59 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
My code looks nice doesn't it. I forgot to add that I moved creation of the SessionFactory into the InitConfiguration method.
Left by Dan on May 21, 2008 8:04 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
I've read elsewhere that you CANNOT use ThreadStatic with NHibernate and ASP.NET. Why do you use it here then? I'm having issues with ASP.NET production application that there ends up being multiple NHibernate sessions retrieving data so the users get weird errors.
Left by James Vander Zanden on Jan 10, 2009 2:57 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
@James: in ASP.NET the UoW is NOT thread static! Have a look at the implementation of the LocalData class where the scenario is handled
Left by Gabriel N. Schenker on Jan 12, 2009 8:39 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
So we call UnitOfWork.Start(). Then use UnitOfWork.CurrentSession, but the factory is not on the ASP.NET session? Or is it? Would it be better to create a IUnitOfWork.Session and use that? That seems to work... Thanks for your help!
Left by James Vander Zanden on Jan 15, 2009 5:48 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
@James: The UoW Factory is created once (and only once) when the application (Web or Win) is started and the UoW class is first accessed. The factory is then available during the lifetime of the application.
Left by Gabriel N. Schenker on Jan 21, 2009 1:34 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Great articles! I am a little puzzled about how you would go about using this in ASP.NET. If you create an IHttpModule with the single job of creating the configuration, then the web-project has to have a reference to NHibernate... right? As far as I can see the only way to configure the UoW is by calling UnitOfWork.Configuration which returns NHibernate.Cfg.Configuration.
Left by Rune on Feb 17, 2009 5:15 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
The NHibernate Session already is a UnitOfWork so I wonder if you need a special pattern to abstract from the session. In most cases it’s likely that you only work with NHibernate as you ORM. If you don’t have the need to support other ORMs than further abstraction is just an intellectual exercise.
Secondly, the session as the UnitOfWork should be kept as short as possible otherwise the identity map will keep on growing and you will get concurrent modification exceptions especially in smart client applications. So, I doubt that it is generally a good idea to keep the session static (either application or thread static) unless you design you application accordingly.
As for web applications, I do believe that each request gets its own thread and the web application container makes sure that two concurrent requests are not handled by the same thread at the same time (this it at least how it’s implemented in J2EE world). Having that in mind, it should be possible to bind the session to the thread when the container starts to handle the request and store it in the session when the request has been handled. I guess that’s mainly what the HTTPContext does as well. But, if you use it in such way, you need to design your application to flush and close the session from time to time and to bind the UnitOfWork (or the NhibernateSession) to the Web session only if you need it across requests.
Left by Carsten on May 25, 2009 4:37 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
I'm having a problem with your code and a multithreaded application. The UI thread dispatches a background thread which syncs some message lists with the database. It all runs fine until the UI thread also does some operation that accesses the database.

One of the threads finishes its work and disposes its UnitOfWork. When the other thread hasn't finished yet, it crashes with an exception that says "You are not in a unit of work".

Something doesn't seem to be thread safe (I'm guessing the session, but it's just a guess). Do you have any clue?
Left by Hans Melis on Jun 04, 2009 4:09 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
>>Something doesn't seem to be thread safe (I'm guessing the session, but it's just a guess). Do you have any clue?

The NHibernate session defenitly is not thread safe.
Left by Carsten on Jun 24, 2009 12:44 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Can someone please solve the thread safe issue!
Left by Jopo on Jul 15, 2009 10:04 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
The Unit Of Work factory has been incorrectly implemented. The CurrentSession property in the UnitOfWorkFactory should be getting/setting ISession from the Local hashtable instead of storing it as a private static variable. Please see Ayande's RhinoCommons implementation of the unit of work, from which this has been derived from.
Left by Bob on Jul 18, 2009 4:51 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Well, I would want to say "good article", but unfortunately I can not. All three parts of this were quite poor. The author for some reason keeps on deviating from the main point of interest here - Unit of work and keeps spending way too much time on TDD, writing more about TDD than the issue at hand. This is a very poor practice and shows that the author has never tried to teach anyone anything - you should keep to the point and be very clear about your intentions. I do not want to read about why you use reflection in your tests - I want to hear about reasons for making something internal/private/protected. I don't care about which mock framework you use, I care about ideas behind UoW, thoughts behind this implementation.

Why bother with hashtables to "store something else"? KISS! This is related to UoW - do not store anything else in there!

Also, why re-invent the wheel if this is a simple rip-off of Aydene's work? What did you bring into it to make it worthwhile?

Sorry for being so harsh, but this is an important topic and having poor articles on official nHibernate web-site is a mistake - a lot of people will end up shooting themselves in a foot by reading this.
Left by Alex on Jul 20, 2009 4:54 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Does this work?
Left by Kevin on Oct 16, 2009 1:21 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
I like the fact that strips out a lot of Ayende's stuff as I'm new to .NET & NHibernate so am finding his code too complex.

Does this implementation work so I can use it for my project?

Regards
Kevin
Left by Kevin on Oct 16, 2009 1:35 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Good explanation, thank you.
Left by work at home blog on Nov 26, 2009 9:38 PM

# SEO India

Requesting Gravatar...
SEO India
Left by SEO India on Dec 05, 2009 4:53 AM

# Pontins

Requesting Gravatar...
Pontins
Left by Pontins on Dec 05, 2009 4:54 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
thank you.
Left by pandora jewelry on Dec 24, 2009 11:53 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
I have a question...Why in your design you tie the UoW factory interface to the Hibernate ISession (IUnitOfWorkFactory.CurrentSession)?, at the beginning of the article you claim that the idea of your design is to abstract the data manipulation from a specific infrastructure (ex. NHibernate, EF, Memory, etc) otherwise you can use ISession in a simple way, so, unless I miss something, it seems the original design goal is broken.
Left by brand new casinos on Dec 30, 2009 10:16 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Thanks for the hint, I was looking for sth. like that for months :-)
Left by Larry blog on Jan 12, 2010 9:04 AM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
best thanks
Left by make money online on Jan 16, 2010 1:15 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
What's more, a bracelet can also be equipped with different small pandora jewelry and even you can change it according to your mood at any time. Here are some meanings of pendant. Small Plane stands for traveling and adventure ; anchor, stability and hope; your baby's boots, having a lot of babies; small feeding pandora bracelets abundant food; Church means happiness and stability of marriage; dragonfly means riches; Eiffel Tower means travel and exploration; four-leaf clover means fortune; horseshoe means luck; Nest means a happy family; bride shows a happy bride in her coming pandora jewelleryship steering shows calming and confidence; pandora ukcoin shows rich marriage life. Wish bone, dreams being about to come true; pandora charm bracelets, love; one heart shot by an arrow, romantic love; purse, wealth; and heart-shaped lock, true love.
Left by kasandra1972 on Jan 29, 2010 12:46 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Left by ugg boot on Feb 08, 2010 7:07 PM

# re: Manage SQL Databases

Requesting Gravatar...
Very cheap, very seductive, to echocardiography. Strongly recommended! ! !
panora jewelry
Left by pandora jewelry pzm on Feb 21, 2010 2:48 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Left by cheap picture frames on Feb 22, 2010 5:55 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Left by cheap picture frames on Feb 22, 2010 6:05 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Left by custom essay writing on Feb 22, 2010 10:20 PM

# 9Dragons gold

Requesting Gravatar...
Do you know9Dragons gold?if you play the online game,you will know9 Dragons goldis the game gold.In the game,if you had morebuy 9 Dragons gold ,you will had a tall level.But if you wantcheap 9Dragons gold,you can come here and spend a little money to bought9Dragons money.Quickly come here
Left by 9Dragons gold on Feb 24, 2010 1:43 PM

# discount Ugg Broome Boots in chestnut leather online sales

Requesting Gravatar...
YS0225A8 Before there was no reason in the world,As now there is!The moncler jackets course of water was my only course,My repetitions oceans' sough and swell ugg adirondack boots!My seasons pleasurable,Before there was no reason in the world,As now there is ugg broome boots!To measure time from sleep I rose to sleep,To measure space I pastured on surprise http://www.edhardy-buy.com/,O meadows of resemblances,I was the grove on whose mosaic floors,The moncler online seeds of otherwis were spent,My gods had many arms,I was the Caesar of unmarshaled grass ugg boots!Faustus in the branches,My first ambitions were my sorrows long!Before there was no reason in the world,As now there is!
Left by discount womens moncler jacket on Feb 24, 2010 11:00 PM

# discount air jordan shoes 23 sales online

Requesting Gravatar...
YS0225A7 when the sun hugs the moon, the sky clses her eyes.when the sun hug the moon the sea quiet her jordans shoes.when the sun hugs the moon,the forest stops her susurrus.when the sun hugs the nike sb dunk high,the desert hodlds her breathe.Thousands of years's waiting is only for this nike acg shoes moment.Never be disappointed.Never give up.It hax been suchlong time.At nike air max 2003 this momentmeet each other in course of time.Do not cry,Moon.I guard you forever.Cause you are in my life,everyting has its meaning.The fascinating Diamond Ring,is the ring i give you,May it give you warm http://www.nikejordanshoes2sell.com/ threduce your tears.Do not cry,Sun,I will be there with you forever/Meeting you has given me precious memeory.The resplendent Baily Beads.is the gem i give you .May i give you cheap air jordan 22 shoes strength, shine in your morning.Meet soon and part soon.It makes peop;e retrospect in spite of lasting a few minutes.A long times waiting is coming.Don't know when the next meeting is .When the sun hugs the Moon. the Moon hugs the sun as well Hugging tightly,regian the lost nicety.
Left by discount nike air max shoes sale on Feb 24, 2010 11:05 PM

# discount air jordan shoes 25 sales online

Requesting Gravatar...
YS0225A6 When you belive,Though hope is frail.It's hard to kill,Who knows what cheap prada shoes miracles,You can achieve,When you belive! Somehow you will,

You will when you belive new nike air max!And in this time of fear, When prayer so often proves in vain, Hope seems like the http://www.nikeaf1jordanshoes.com/summer birds. Too swiftly flown away, And now I am standing wholesale gucci shoes here.My heart's so full I can't explain.Seeking faith and speaking women's nike shox wordsr thought I'd say, They don't always happen when you ask authentic air jordan shoes.And it's easy to give in to your fear. But when you're blinded by your pain!
Left by discount mens moncler down coat on Feb 24, 2010 11:09 PM

# discount ed hardy women long sleeve shirts sales online

Requesting Gravatar...
YS0225A5 If you think you are beaten, you are! If you think you dare noted hardy clothing, you don't! If you want to win but think you can't, It's almost a cinch you won't ed hardy hoodies! If you think you'll lose,you're lost! For out of the world we find.Success begins with a fellow's will,It's all in a ed hardy shirts state of mind! Life's battles don'tlways go.To the stronger and faster ed hardy coats man,But sooner or later the man who wins,Is the man who thinks he can! When You Belive http://www.edfashionclothes.com/,Many night we've prayed!With no proof anyone could hear!In our heart a hopeful moncler online store song,we barely understood!Now we are not afraid !Although we know there's much to fear!We were moving the moncler jackets mountian long,Before we knew we could!There can be miracles!
Left by discount mens moncler down coat on Feb 24, 2010 11:13 PM

# discount christian louboutin sandals online sales

Requesting Gravatar...
YS0226A1 That your heart has been broken,Hear the words,I'm he, my child,;And know your christian louboutin uk angel has spoken.For even in the darkest hour,When all of discount louboutin shoes hope seems gone,They'll give you strength to live your life,And desire to go on.And if your faith in Heaven, Should ever fade away,They'll help renew your christian louboutin boots spirit, And help you find your way.Even though you're ever filled with doubt, About the christian louboutin pumps life you live,Know that they are there to give you All that they can give.For you see, the Father sent them,Because to Him, you mean so much,That He sent them just for you,my louboutin sale friend,And your life, they will touch.They will always be here,They will never leave your http://www.christianlouboutinshoestore.com/ side;And upon their strength and guidance,You always may rely.Take comfort in their guidance, Draw strength from up above,And know that their sweet presence,Is God's precious gift of love.
Left by cheap christian louboutin shoes on Feb 25, 2010 3:35 PM

# discount women's ugg elsey boots 5596 sales online

Requesting Gravatar...
YS0226A2 If I were a boy again, I would practice perseverance more often, nd never give up a thing because it was ugg australia boots or inconvenient. If we want light, we must conquer darkness. Perseverance can sometimes equal genius cheap ugg boots in its results. “There are only two creatures,” syas a proverb, “who can surmount the pyramids—the eagle and the snail.” If I were a uggs sale boy again, I would school myself into a habit of http://www.topsnowboots.com/ attention; I would let nothing come between me and the subject in hand. I would remember that a good skater never tries to skate in two ugg cardy boots directions at once. The habit of attention becomes part of our life, if we begain early enough. I often hear cheap gucci shoes grown up people say “ I could not fix my attention on the sermon or ugg coquette book, although I wished to do so” , and the reason is, the habit was not formed in youth.
Left by cheap ugg upside boots 5163 on Feb 25, 2010 3:40 PM

# discount Women's ugg adirondack boots II sales online

Requesting Gravatar...
YS0226A3 Hold fast to dreams.For if dreams die. Life is a brken-winged bird,That ugg australia boots can never fly.Hold fast to dreams. For when dreams go,Life is a barren ugg tall boots field, Frozen only with snow !You never know until you try; And you never try unless you really try ugg cardy boot. You give it your best shot; You do the best you can. And if you have done everything http://www.uggsnowbootsbest.com/! In your power,and still,The truth of the uggs argyle knit matter is! That you haven\'t failed at all.When you reach for your dreams,No matter what ugg boots they may be,You grow from the reaching;You learn from the trying;You win from the doing.
Left by cheap ugg classic cardy boots on Feb 25, 2010 3:48 PM

# discount reebok nfl jerseys online sales

Requesting Gravatar...
YS0226A4 A true friend is someone who reaches r your hand and touches your cheap hockey jerseys heart.There's always going to be people that hurt you,so what you have to do is keep on trusting nfl jerseys and just be more careful about who sport jerseys you trust next time around.Make youself a better person and know who you are discount nba jerseys before you try and know someone else and expect them to know you mlb jerseys on sale.Remember:Whatever happens,happens for a reason.How many people actually have 8 true http://www.nfljerseymlb.com/friends Hardly anyone I know.But some of us have all right friends and good friends.
Left by cheap adiads nba jerseys sale on Feb 25, 2010 3:50 PM

# discount ugg sienna miller boots 5818 sales online

Requesting Gravatar...
YS0226A9 Unwearied still, lover by lover,They paddle in the cold,Comanionable ugg australia shoes streams or climb the air;Their hearts have not grown old;ugg coquette Passion or conquest, wander where they will, Attend upon them still ugg adirondack boots. But now they drift on the still water, Mysterious, beautiful; Among what http://www.uggboots4buy.com/ rushes will they build, By what lake’s edge or pool,Delight men’s mbt shoes eyes when I awake some day.To find they have flown uggs classic cardy away?Before there was no reason in the world As now there is I was the bough bent easy by a ugg boots bird I was the vague blue-grazing flock The sleeping and invisible!
Left by cheap women's ugg elsey boots on Feb 25, 2010 3:57 PM

# discount mens air jordan shoes 13 online sales

Requesting Gravatar...
YS0226A10 When you are old and gray and full of seep,And nodding by the moncler jackets fire, take down this book! And slowly read jordans sheoes , and dream of the soft look,Your eyes had once, and of their cheap nike shoes shadows deep;How many loved your moments of glad grace,And loved your beauty with nike air force 1 love false or true; But one man loved the pilgrim soul in you,And http://www.onestop-onlineshopping.com/ loved the sorrows of your changing face; And bending down beside the designer clothing glowing bars,Murmur, a little sadly, how love fled.And paced upon the mountains overhead discount air jordan shoes,And hid his face amid a crowd of stars.
Left by cheap nike air max 90 online on Feb 25, 2010 4:00 PM

# discount louis vuitton damier canvas handbags online sales

Requesting Gravatar...
YS0226A11 Surrounding you are angels,They are there t guide your path.If designer purses weaesskn overcomes you,They'll give you strength if you will ask. They are your protection.When discount designer bags on sale life seems too hard to bear,And though you feel alone at tis, The louis vuitton 2009 angels ... they are there.Their faces may be hidden And their voices you might not hear,But they are ALWAYS with you,Through your laughter or your tears.http://www.handbags4buy.com/ They'll walk along beside you,They'll guide your leather handbags steps along the way, They'll comfort you and hold you,Protect you dior handbags night and day.They'll hold to your hand tightly ,They'll not ever let it go,And they'll gently lead you cheap designer handbagsforward,Taking each step very slow.For even as you slumber,They watch closely over you;They are there beside you. In each and every thing you do.
Left by cheap nike air max 90 online on Feb 25, 2010 4:09 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...

wedding dresses,wedding gowns,bride dresses,bridesmaids dresses,evening dresses,bridal gowns,flower girl dresses
Wedding Gowns
Formal Gowns
Cocktail Gowns
Find the wedding dress designer and wedding dress that's right for you! Browse dresses from
Bridesmaid Gowns
Evening Gowns
View our selection of exquisite, handmade gowns and dresses for your wedding
Wedding Dresses, Wedding Shoes and Wedding Accessories from wedding shop, the UK's finest collection of designer wedding dresses.
Use the wedding dress and
cheap wedding
wedding dresses
wedding shop
er
Left by sbb on Feb 27, 2010 10:11 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...

The world is cute just because of them. What will the fashion people in streets do?You See, Christian louboutin sale Direct the Fashion Trend of Detroit. The present young people like to dress themselves up different, in any case just to look like different from others. In the List of Most Welcomed Embellishments, christian louboutin uk are the NO.1 Therefore, we can often see many fantastic impersonations that may be fashionable, strange, or alternative in louboutin sale.Habits that Stimulate Excoriation to louboutin shoes uk, everyone has their own views christian louboutin, and then let's follow the street snaper to have a look at them in the Occident. Why Shop louboutin for WaitressesHey Colorists! Keep Away from louboutin shoes!


Special skirt with big lattices is rare. Have a Christian louboutin shoes and maybe you can obtain an unexpected effect louboutin shoes. The suit ysl shoes upper body doesn't feel obtrusive, probably because of colour assortment is syncretic. So there can be such good effect.


Left by christian louboutin on Mar 01, 2010 8:46 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Very great post.
Left by ucvhost on Mar 06, 2010 2:47 AM

# ugg boots

Requesting Gravatar...


they are very good and useful!!!
ugg outlet
cheap uggs
nike shoes
wholesale watches
Left by ugg boots on Mar 07, 2010 5:28 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Back in Time It’s hard to find knowledgeable people on this topic, but you sound like you know what you’re talking about! Thanks Don’t stop writing, you’ve given me lots of good info! Youtube to MP4 Converter
Convert PDF to image
Left by powerpoint on Mar 08, 2010 2:27 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
My hair is just over my ears. I like two kinds of hair styles most. Firstly, use the ghd straighteners to make

the hair in nature and bouffant style. Divide the hair into several portions. Use ghd pink to roll them inside

towards your ears. Several minutes later, the hair will roll neatly inside in the branches. Secondly, the active and energetic style with the roll of the

direction in the opposite direction can be made similarly with the formal procedure. All you need to do is to roll the hair outward instead of inward

with ghd mk5.
It is so simple that you can have your own charming short hair style with GHD straightener uk. Besides the new hair styles,ghd straighteners can help you with the puffy hair after you get up which is the annoying thing for many short hair

girls.
So as long as I have the good tool of ghd pink, no matter what the fashion trend goes of hair styles, I will

stick into my favorite neat short hair., the active and energetic style with the roll of the direction in the opposite direction can be made similarly with the

formal procedure. All you need to do is to roll the hair outward instead of inward with GHD hair straightener.
It is so simple that you can have your own
Left by ghd straighteners on Mar 09, 2010 3:32 PM

# re: NHibernate and the Unit of Work pattern (Part 3)

Requesting Gravatar...
Whenever I hear friends talking about mbt, my feeling would always be a painful mixture of envy and

helplessness. As a matter of fact, I have long been craving about possessing a pair of MBT shoes. To a girl of low stature as me, a pair of mbt shoes could make me seem more slender or least won't be dwarfed by other girls. But its high price always

makes me feel hard to afford due to my restrained financial conditions.
But not long ago, a friend of mine sent me a pair of mbt shoes sale which thrilled me up for several days.

It's not until then that did I realize each penny for it is well paid. Indeed, it really deserves such a high price. I'm only regretting that I didn't

buy one earlier.
I'm only regretting that I didn't buy one earlier.
Left by ghd pink on Mar 09, 2010 3:39 PM

Your comment:

 (will show your gravatar)
 
Please add 6 and 6 and type the answer here: