Archive for June, 2008

Managing your NHibernate Sessions

Note: you can find a more recent post on this concept here.

I was working on my northwind sample application (which i'll post about as soon as i get something that's worth showing) and i was struggling to find a clean way to manage my NHibernate sessions. I wanted a way to create a session once you enter the service layer, and that session should be available transparently to the repository implementations without actually having to constantly pass it around. But i didn't just want to store it somewhere and have all the classes that needed the current session get it directly from that place. Also, i didn't want the current session to be available to everyone. Another important requirement was to have maximum flexibility for writing tests. I could just use Rhino-Commons' implementations of the UnitOfWork and Repository patterns and be done with it, but where's the fun in that? And since this application is mostly a learning experience i figured i should try to write this myself. After a bit of searching and experimenting, i finally came up with a way that i'm happy with (for now anyways). Let's have a look.

To illustrate what i want, take a look at this made-up method in my service layer:

        public ProductCategoryDTO[] GetAllProductCategories()

        {

            using (ISession session = GetNewSession())

            {

                var repository = GetProductCategoryRepository();

                var categories = repository.GetAllProductCategories();

                return categories.ToDTOs();

            }

        }

This is just some example code, it doesn't even work. But it's kinda what i want... The thing is, i don't want to deal directly with the ISession type in the service layer, but i do want the ProductCategoryRepository to use the ISession that is created within the context of this method call.

NHibernate's ISession type is an implementation of the Unit Of Work pattern. I don't want to use the ISession directly in my service layer because i want something that is a bit more high-level. Basically just something that would allow me to work within an NHibernate session, and provide me with the ability to flush changes to the database whenever i want to. And obviously, i want it to allow me to create a transaction as well. So i came up with the following unit of work interface:

    public interface IUnitOfWork : IDisposable

    {

        /// <summary>

        /// Flushes any changes that haven't been executed yet

        /// </summary>

        void Flush();

 

        /// <summary>

        /// Creates an ITransaction instance with the ReadCommitted isolation level

        /// </summary>

        /// <returns></returns>

        ITransaction CreateTransaction();

 

        /// <summary>

        /// Creates an ITransaction instance with the given isolation level

        /// </summary>

        /// <param name="isolationLevel"></param>

        /// <returns></returns>

        ITransaction CreateTransaction(IsolationLevel isolationLevel);

    }

This interface pretty much offers me anything i'm concerned with in my service layer. The real implementation would do a bit more though... It has to create an NHibernate session and make it available to the repositories in a clean way. Here's the thing though... the repositories have a completely different lifetime than the NHibernate sessions. The NHibernate session has to be created when we enter a service method, and it has to be valid within the scope and context of the execution of that service method. The repositories however stay alive for the lifetime of the application so they can't just hold a reference to an NHibernate session. Every time you call a method of a repository, it has to find out which session it should use, which is the session that is being used in the context of the current service method call. Now, we could always pass around the session but that really doesn't look good and is cumbersome. So i basically need something that gives me access to the active nhibernate session:

    public interface IActiveSessionManager

    {

        /// <summary>

        /// Returns the active ISession for the current thread. Throws exception if there's

        /// no active ISession instance

        /// </summary>

        /// <returns></returns>

        ISession GetActiveSession();

 

        /// <summary>

        /// Sets the active ISession for the current thread. Throws exception if there's

        /// already an active ISession instance

        /// </summary>

        /// <param name="session"></param>

        void SetActiveSession(ISession session);

 

        /// <summary>

        /// Clears the active ISession for the current thread.

        /// </summary>

        void ClearActiveSession();

    }

That gives me the ability to retrieve and set the active session on a per-thread basis. After all, a service method call will be handled by one thread, so setting the active session for that current thread is a convenient way to store the session.

Now i still need something that takes care of creating the NHibernate sessions:

    public interface ISessionFactory

    {

        /// <summary>

        /// Creates a new ISession instance

        /// </summary>

        /// <returns></returns>

        ISession Create();

    }

Ok, so what do we have so far? An interface to define the functionality that a UnitOfWork should offer at the service level. An interface to store/retrieve the active session on the current thread, and finally, an interface to actually create the NHibernate session. Let's start looking at the real implementations. Here's the code to the SessionFactory class:

    public class SessionFactory : ISessionFactory

    {

        private readonly NHibernate.ISessionFactory sessionFactory;

 

        public SessionFactory()

        {

            Configuration configuration = new Configuration()

                .Configure()

                .AddAssembly("Northwind");

 

            sessionFactory = configuration.BuildSessionFactory();

        }

 

        public ISession Create()

        {

            return sessionFactory.OpenSession();

        }

    }

Pretty straightforward... it initializes NHibernate and gives us the ability to ask for new sessions. So how are we going to make these sessions available to our repositories? Through the ActiveSessionManager class of course:

    public class ActiveSessionManager : IActiveSessionManager

    {

        [ThreadStatic]

        private static ISession current;

 

        public ISession GetActiveSession()

        {

            if (current == null)

            {

                throw new InvalidOperationException("There is no active ISession instance for this thread");

            }

 

            return current;

        }

 

        public void SetActiveSession(ISession session)

        {

            if (current != null)

            {

                throw new InvalidOperationException("There is already an active ISession instance for this thread");

            }

 

            current = session;

        }

 

        public void ClearActiveSession()

        {

            current = null;

        }

    }

It basically just stores the session in a ThreadStatic field, which means that each thread will have a different static reference for this field. So if we set the active session through the SetActiveSession method in thread X, and thread Y also sets an active session, the GetActiveSession method will return the correct session instances for each thread.

So now we have everything we need to create our UnitOfWork class:

    public class UnitOfWork : Disposable, IUnitOfWork

    {

        private readonly IActiveSessionManager activeSessionManager;

        private readonly ISession session;

 

        public UnitOfWork(ISessionFactory sessionFactory, IActiveSessionManager activeSessionManager)

        {

            this.activeSessionManager = activeSessionManager;

            session = sessionFactory.Create();

            activeSessionManager.SetActiveSession(session);

        }

 

        protected override void DisposeObjects()

        {

            if (session != null)

            {

                session.Close();

                session.Dispose();

            }

        }

 

        protected override void ClearReferences()

        {

            activeSessionManager.ClearActiveSession();

        }

 

        public void Flush()

        {

            session.Flush();

        }

 

        public ITransaction CreateTransaction()

        {

            return CreateTransaction(IsolationLevel.ReadCommitted);

        }

 

        public ITransaction CreateTransaction(IsolationLevel isolationLevel)

        {

            return session.BeginTransaction(isolationLevel);

        }

    }

When the UnitOfWork is created, it receives an ISessionFactory instance, and an IActiveSessionManager instance. It then creates a new session through the ISessionFactory and uses the IActiveSessionManager to make sure that session is the active session for the current thread. When the UnitOfWork is disposed, it closes and cleans up the session and it also uses the IActiveSessionManager to clear the active session for the current thread. Oh and it obviously also provides implementations for what it is we actually need in our service layer: flushing the changes whenever we want and creating transactions.

The ISessionFactory and IActiveSessionManager instances should stay alive as long as the application is alive. But as you could see in the implementations of those types, we didn't write any code to deal with their lifetimes. I'm actually relying on my IoC container for that. In the class where my container is set up, you'll find the following code:

        private static void RegisterUnitOfWorkComponents()

        {

            Register(Component.For<ISessionFactory>()

                .ImplementedBy<SessionFactory>().LifeStyle.Singleton);

            Register(Component.For<IActiveSessionManager>()

                .ImplementedBy<ActiveSessionManager>().LifeStyle.Singleton);

            Register(Component.For<IUnitOfWork>()

                .ImplementedBy<UnitOfWork>().LifeStyle.Transient);

        }

ISessionFactory and IActiveSessionManager are registered as singleton instances, so whenever these types are requested, the same instances will be returned. The IUnitOfWork type is registered with a transient lifetime, so whenever it is requested, the container will create a new UnitOfWork class and pass the ISessionFactory and IActiveSessionManager instances to the constructor.

Right, we've taken care of creating the session, associating it with the current thread and making it available in a nice and clean way. Now we actually have to make sure our repositories can use it. In the base repository implementation, you can find the following code:

        private readonly IActiveSessionManager activeSessionManager;

 

        public Repository(IActiveSessionManager activeSessionManager)

        {

            this.activeSessionManager = activeSessionManager;

        }

 

        protected ISession Session

        {

            get { return activeSessionManager.GetActiveSession(); }

        }

Whenever a repository needs a session, it just needs to use the protected Session property and it will get the session that is associated with the current thread.

So now we can rewrite our made-up service method from earlier to the following:

        public ProductCategoryDTO[] GetAllProductCategories()

        {

            using (Container.Resolve<IUnitOfWork>())

            {

                var repository = Container.Resolve<ProductCategoryRepository>();

                var categories = repository.GetAllProductCategories();

                return categories.ToDTOs();

            }

        }

We know that the NHibernate session will be created, and more importantly, that it is not just globally accessible to everyone. It can only be accessed when you have a reference to an IActiveSessionManager instance. We also don't need to pass around the session all the time so our code is a bit more concise, showing only the intent of what we're trying to do without distracting us with details that are not relevant to that intent. We also have a lot of flexibility to write tests... i can write tests for my repositories without having to create a UnitOfWork... i can simply pass a fake IActiveSessionManager to my repositories when i'm testing them and have it return the session that i'm using for my test. All in all, this approach offers me with a lot of advantages, without ugly disadvantages. Well, at this moment i don't really see any disadvantages so if you do see some, please let me know :)

Disposing of the IDisposable implementation

19 commentsWritten on June 17th, 2008 by
Categories: Memory Management, Patterns, Performance

Everytime i need to implement the IDisposable interface i have to lookup the recommended way of doing so. That in itself is a bad sign, so i figured i might as well get rid of this by putting the implementation in a reusable base class, based on the officially recommended way:

    public abstract class Disposable : IDisposable
    {
        private bool disposed;
 
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
        protected void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    DisposeManagedResources();
                }
 
                DisposeUnmanagedResources();
                disposed = true;
            }
        }
 
        protected void ThrowExceptionIfDisposed()
        {
            if (disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
        }
 
        protected abstract void DisposeManagedResources();
        protected virtual void DisposeUnmanagedResources() {}
    }

So now i can simply inherit from Disposable, and i just need to implement the two abstract methods. Here's a made up example to illustrate this:

    public class MyExpensiveResource : Disposable
    {
        private FileStream fileStream;
        private MemoryStream memoryStream;
 
        public MyExpensiveResource(string path)
        {
            fileStream = new FileStream(path, FileMode.Open);
            memoryStream = new MemoryStream();
        }
 
        public void DoSomething()
        {
            ThrowExceptionIfDisposed();
 
            // ... something
        }
 
        protected override void DisposeManagedResources()
        {
            if (fileStream != null) fileStream.Dispose();
            if (memoryStream != null) memoryStream.Dispose();
        }
    }

Obviously, you can't use the Disposable base class if you're already inheriting from another base class so in that case you'd still have to implement the IDisposable interface.

Update: Here's a thread-safe version of this idea.

Are women better developers than men?

14 commentsWritten on June 16th, 2008 by
Categories: Software Development

A coworker just pointed out the following article. This is something i'm pretty interested in. Let's just get to the two most important quotes from the article:

"Women are more touchy-feely and considerate of those who will use the code later, she says. They’ll intersperse their code with helpful comments and directions, explaining why they wrote the lines the way they did and exactly how they did it. The code becomes a type of “roadmap” for others who might want to alter it or add to it later"

and...

"Men, on the other hand, have no such pretenses. They try to show how clever they are by writing very cryptic code. They try to obfuscate things in the code and don’t leave clear directions for people using it later."

I wouldn't be surprised if this was actually true, to be honest. Allthough there are always exceptions of course (no pun intended). But how many of us have been confronted with cryptic code with hardly any comments to clarify the code? How likely was it that that code was written by a male developer? Since there aren't that many female developers, i'd say the odds are pretty high it was written by a guy. Now, i don't believe men write crappy code on purpose though. But considering how common crappy code really is, while keeping in mind that most developers are male, and that women in general think differently than men, is it really that hard to believe that women might actually be better at this?

The subject of female programmers is one that is occasionaly brought up among male developers. And you'll very often hear them say "i've never known one who was good at coding". I've even heard some developers claim that it is impossible for women to be good at coding. Most of them simply don't believe in it. Me, honestly, i don't know... i know a lot of male programmers, but i really don't know a lot of them that are actually good. I would guess that only 10% of male developers is actually good. I obviously have no studies or facts or figures to back that up, it's just a guesstimate based on the total numbers of coders i've met so far. But if you think about that, it's not at all unlikely that the percentage of good programmers could actually be higher among women. I mean come on, 10%?! That shouldn't be hard to beat. If only there were more female programmers we might actually be able to get some real data on all of this. But until then, put me in the 'believer'-camp :)

Automanual Dependency Injection?

I apologize in advance for using the term 'automanual' but if you've been reading this blog for a while you already know i completely suck at coming up with good names. So bear with me, and you'll probably understand what i mean as you work your way through this post. It really is pretty cool... i promise :p

I'm playing around with some supervising controller MVP stuff using regular ASP.NET webforms. Yes i know, i should be using ASP.NET MVC but i have a strict "i don't touch it before there's a final release"-policy when it comes to Microsoft products (as opposed to my "lemme just build the latest version of the trunk"-policy for various open source products). Anyways, what i'm trying to do is pretty simple. I have a view (ProductList.aspx) which uses a supervising controller (ProductListController). The view (the aspx page) will notify the controller when it needs to do something through events. The controller will then do whatever it needs to do and it will send the data back to the view through properties of the view. If that's not clear to you, read the post i linked to for a much better and detailed explanation.

Since ASP.NET automatically instantiates your aspx page, the easiest thing to do is to let the view create the controller and then pass itself as a parameter to the controller. But the controller also has other dependencies, such as a service which exposes the business logic that we need for this screen. So i have two options: i either create the controller myself and provide all the dependencies, or i use an inversion of control container to create the controller and to wire up all the dependencies. I don't want to have to modify my view code whenever i add/remove a dependency of the controller, so i go with the inversion of control container.

Suppose the constructor of the controller looks like this:

        public ProductListController(IProductList view, IProductsService productsService)

        {

            this.view = view;

            this.productsService = productsService;

        }

Here's where it gets tricky... since the view (which implements the IProductList interface) is asking the container to create a ProductListController, how can the container pass the correct IProductList dependency to the controller? We can't use the regular dependency look-up mechanisms because our controller actually needs the current view instance, but that view instance is asking the container to create the controller! By default, the container has no way whatsoever to resolve the IProductList dependency to the current view instance. So basically, what we want to do in this case is to manually provide the view dependency, but still have the container automatically provide the IProductsService dependency (hence the term 'automanual' which you have to admit is starting to sound pretty good at this point, right?). And of course, we want all of this to work automagically.

It turns out that Castle's Windsor actually does have some slick tricks to make this work. Here's how we can create the controller through the container from the view:

            IProductListController controller =

                Container.Resolve<IProductListController>(new { view = this });

Told you it was slick! It's pretty easy actually... the parameter we pass to the Resolve method is an instance of an anonymous type with a view property. We set the view property to the current aspx instance (using the 'this' keyword obviously) and Windsor is smart enough to figure out that this value should be used to satisfy the view dependency instead of using it's normal look-up mechanisms. The result is that our controller has a reference to the current view, and its IProductsService reference is resolved as the container would typically resolve dependencies. Pretty sweet.

Btw, i googled the term 'automanual' and sure enough, it already exists... but it's not really used in the context of writing code so if this thing sticks, remember where you heard it first ;)

The Query Batcher

4 commentsWritten on June 14th, 2008 by
Categories: NHibernate, Performance

One of my favorite NHibernate features must be the MultiCriteria/MultiQuery support. This basically allows you to execute a set of queries in one database call. In case you don't know, an ICriteria instance is basically a programmatic query. If you use MultiCriteria, you can batch either ICriteria or DetachedCriteria instances. And if you use MultiQuery, you can batch regular HQL strings, IQuery instances (which are in fact also HQL queries) or references to named queries.

That gives you quite a few options to batch your queries. The only downside to using MultiCriteria and/or MultiQuery is that you have to retrieve the results with an index, based on the order in which you added the criteria or queries. Using index values in your code often reduces readability, so if i can i try to avoid using them.

So i wrote a little QueryBatcher class which allows me to retrieve the results based on a key value. The class supports MultiCriteria as well as MultiQuery so you can use it to batch all kinds of queries. I didn't find a way to combine the batched criteria and the batched HQL queries in one database call, so if you mix criteria with hql queries, it will use one database call to execute all the criteria, and one database call to execute the hql queries.

And now i can write code like this:

        [Test]

        public void ReturnsProperResultsWhenUsingMultipleQueries()

        {

            queryBatcher.AddCriteria("Products", session.CreateCriteria(typeof(Product)));

            queryBatcher.AddCriteria("Suppliers", DetachedCriteria.For<Supplier>());

            queryBatcher.AddHqlQuery("ProductCategories", "from ProductCategory");

            queryBatcher.AddHqlQuery("SomeProducts",

                session.CreateQuery("from Product where Discontinued = :discontinued")

                        .SetBoolean("discontinued", false));

 

            Assert.That(queryBatcher.GetEnumerableResult<Product>("Products").Count() > 0);

            Assert.That(queryBatcher.GetEnumerableResult<Supplier>("Suppliers").Count() > 0);

            Assert.That(queryBatcher.GetEnumerableResult<ProductCategory>("ProductCategories").Count() > 0);

            Assert.That(queryBatcher.GetEnumerableResult<Product>("SomeProducts").Count() > 0);

        }

Obviously, this is a very simple example with extremely simple queries... but you can of course batch very complex queries with this as well. You can also add queries that return scalar values so you could for instance do do something like queryBatcher.GetSingleResult<long>("TotalOutstandingAmount") and it would return that scalar value.

This is the code of the QueryBatcher class:

    public class QueryBatcher : IQueryBatcher

    {

        private readonly Dictionary<string, int> criteriaResultPositions;

        private readonly List<ICriteria> criteriaList;

        private readonly List<IQuery> hqlQueryList;

        private readonly Dictionary<string, int> queryResultPositions;

        private readonly ISession session;

 

        private IList criteriaResults;

        private IList queryResults;

 

        public QueryBatcher(IActiveSessionManager activeSessionManager)

        {

            session = activeSessionManager.GetActiveSession();

            criteriaList = new List<ICriteria>();

            hqlQueryList = new List<IQuery>();

            criteriaResultPositions = new Dictionary<string, int>();

            queryResultPositions = new Dictionary<string, int>();

        }

 

        public void AddCriteria(string key, ICriteria criteria)

        {

            criteriaList.Add(criteria);

            criteriaResultPositions.Add(key, criteriaList.Count - 1);

        }

 

        public void AddCriteria(string key, DetachedCriteria detachedCriteria)

        {

            AddCriteria(key, detachedCriteria.GetExecutableCriteria(session));

        }

 

        public object GetResult(string key)

        {

            ExecuteQueriesIfNecessary();

            object result = GetResultFromList(key, criteriaResults, criteriaResultPositions);

            if (result != null) return result;

            result = GetResultFromList(key, queryResults, queryResultPositions);

            if (result != null) return result;

 

            return null;

        }

 

        public IEnumerable<T> GetEnumerableResult<T>(string key)

        {

            var list = GetResult<IList>(key);

            return list.Cast<T>();

        }

 

        public T GetSingleResult<T>(string key)

        {

            var result = GetResult<IList>(key);

            return (T)result[0];

        }

 

        public void AddHqlQuery(string key, IQuery query)

        {

            hqlQueryList.Add(query);

            queryResultPositions.Add(key, hqlQueryList.Count - 1);

        }

 

        public void AddHqlQuery(string key, string query)

        {

            AddHqlQuery(key, session.CreateQuery(query));

        }

 

        public void ExecuteQueriesIfNecessary()

        {

            ExecuteCriteriaIfNecessary();

            ExecuteHqlIfNecessary();

        }

 

        private void ExecuteCriteriaIfNecessary()

        {

            if (criteriaList.Count > 0 && criteriaResults == null)

            {

                if (criteriaList.Count == 1)

                {

                    criteriaResults = new ArrayList { criteriaList[0].List() };

                }

                else

                {

                    var multiCriteria = session.CreateMultiCriteria();

                    criteriaList.ForEach(c => multiCriteria.Add(c));

                    criteriaResults = multiCriteria.List();

                }

            }

        }

 

        private void ExecuteHqlIfNecessary()

        {

            if (hqlQueryList.Count > 0 && queryResults == null)

            {

                if (hqlQueryList.Count == 1)

                {

                    queryResults = new ArrayList { hqlQueryList[0].List() };

                }

                else

                {

                    var multiQuery = session.CreateMultiQuery();

                    hqlQueryList.ForEach(q => multiQuery.Add(q));

                    queryResults = multiQuery.List();

                }

            }

        }

 

        private T GetResult<T>(string key)

        {

            return (T)GetResult(key);

        }

 

        private static object GetResultFromList(string key, IList list, IDictionary<string, int> positions)

        {

            if (positions.ContainsKey(key)) return list[positions[key]];

            return null;

        }

    }