From 3f9b5c878ee354cf583b54f51056a2cee89e4f3e Mon Sep 17 00:00:00 2001 From: Andre Azevedo Date: Tue, 9 Aug 2011 20:42:40 -0300 Subject: [PATCH] NHibernate infrastructure. related #1 --- .../Database/IDatabaseSessionFactory.cs | 32 ++++++ .../Database/UnitOfWork.cs | 63 ++++++++++ .../WebBasedDatabaseSessionFactory.cs | 108 ++++++++++++++++++ .../PetStore.Infrastructure.NHibernate.csproj | 31 ++++- src/PetStore.sln | 6 + 5 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 src/PetStore.Infrastructure.NHibernate/Database/IDatabaseSessionFactory.cs create mode 100644 src/PetStore.Infrastructure.NHibernate/Database/UnitOfWork.cs create mode 100644 src/PetStore.Infrastructure.NHibernate/Database/WebBasedDatabaseSessionFactory.cs diff --git a/src/PetStore.Infrastructure.NHibernate/Database/IDatabaseSessionFactory.cs b/src/PetStore.Infrastructure.NHibernate/Database/IDatabaseSessionFactory.cs new file mode 100644 index 0000000..a1c48b8 --- /dev/null +++ b/src/PetStore.Infrastructure.NHibernate/Database/IDatabaseSessionFactory.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NHibernate; + +namespace PetStore.Infrastructure.NHibernate.Database +{ + /// + /// NHibernate sessions manager + /// + public interface IDatabaseSessionFactory + { + /// + /// Open a NHibernate Session + /// + /// NHibernate Session. + ISession Retrieve(); + + /// + /// Opens an independent NHibernate Session. + /// WARNING: Sessions opened independently must be manually closed! + /// + /// Session + ISession OpenIndependentSession(); + + /// + /// Closes the NHibernate Session. + /// + void Close(); + } +} diff --git a/src/PetStore.Infrastructure.NHibernate/Database/UnitOfWork.cs b/src/PetStore.Infrastructure.NHibernate/Database/UnitOfWork.cs new file mode 100644 index 0000000..dd98bd3 --- /dev/null +++ b/src/PetStore.Infrastructure.NHibernate/Database/UnitOfWork.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using NHibernate; +using PetStore.Core.Infrastructure.InversionOfControl; +using PetStore.Core.Infrastructure.UnitOfWork; + +namespace PetStore.Infrastructure.NHibernate.Database +{ + public class UnitOfWork : IUnitOfWork + { + private static readonly Dictionary Transactions = new Dictionary(); + private readonly object _sync = new object(); + private readonly bool _isChild; + private bool _commited = false; + + public UnitOfWork() + { + lock (_sync) + { + if (Transactions.ContainsKey(Thread.CurrentThread.ManagedThreadId)) + { + _isChild = true; + } + else + { + Transactions.Add(Thread.CurrentThread.ManagedThreadId, IoC.Resolve().Retrieve().BeginTransaction()); + _isChild = false; + } + } + } + + public void Commit() + { + if (!_isChild) + { + lock (_sync) + { + Transactions[Thread.CurrentThread.ManagedThreadId].Commit(); + _commited = true; + } + } + } + + public void Dispose() + { + if (!_isChild) + { + lock (_sync) + { + if (!_commited) + { + Transactions[Thread.CurrentThread.ManagedThreadId].Rollback(); + } + Transactions[Thread.CurrentThread.ManagedThreadId].Dispose(); + Transactions.Remove(Thread.CurrentThread.ManagedThreadId); + } + } + } + } +} diff --git a/src/PetStore.Infrastructure.NHibernate/Database/WebBasedDatabaseSessionFactory.cs b/src/PetStore.Infrastructure.NHibernate/Database/WebBasedDatabaseSessionFactory.cs new file mode 100644 index 0000000..38401e6 --- /dev/null +++ b/src/PetStore.Infrastructure.NHibernate/Database/WebBasedDatabaseSessionFactory.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using NHibernate; +using NHibernate.Cfg; + +namespace PetStore.Infrastructure.NHibernate.Database +{ + /// + /// Database session factory for WEB apps. + /// Based on Request Context. + /// + public class WebBasedDatabaseSessionFactory : IDatabaseSessionFactory + { + #region Fields + + private const string CurrentSessionKey = "nhibernate.current_session"; + private static ISessionFactory _sessionFactory; + private static object _sessionFactorySync = new object(); + + #endregion + + #region Properties + + public static ISessionFactory SessionFactory + { + get + { + if (_sessionFactory == null) + { + lock (_sessionFactorySync) + { + if (_sessionFactory == null) + { + _sessionFactory = new Configuration().Configure().BuildSessionFactory(); + } + } + + } + return _sessionFactory; + } + } + + #endregion + + #region Constructors + + static WebBasedDatabaseSessionFactory() + { + SetupProfiler(); + } + + #endregion + + #region IDatabaseSessionFactory Members + + public ISession Retrieve() + { + HttpContext context = HttpContext.Current; + ISession currentSession = context.Items[CurrentSessionKey] as ISession; + + if (currentSession == null) + { + currentSession = SessionFactory.OpenSession(); + currentSession.FlushMode = FlushMode.Never; + context.Items[CurrentSessionKey] = currentSession; + } + + return currentSession; + } + + public ISession OpenIndependentSession() + { + ISession session = SessionFactory.OpenSession(); + session.FlushMode = FlushMode.Never; + return session; + } + + public void Close() + { + HttpContext context = HttpContext.Current; + ISession currentSession = context.Items[CurrentSessionKey] as ISession; + + if (currentSession == null) + { + return; + } + + currentSession.Close(); + context.Items.Remove(CurrentSessionKey); + } + + #endregion + + #region Private Methods + + private static void SetupProfiler() + { +#if DEBUG + HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); +#endif + } + + #endregion + } +} diff --git a/src/PetStore.Infrastructure.NHibernate/PetStore.Infrastructure.NHibernate.csproj b/src/PetStore.Infrastructure.NHibernate/PetStore.Infrastructure.NHibernate.csproj index b34e691..e81d1a4 100644 --- a/src/PetStore.Infrastructure.NHibernate/PetStore.Infrastructure.NHibernate.csproj +++ b/src/PetStore.Infrastructure.NHibernate/PetStore.Infrastructure.NHibernate.csproj @@ -5,7 +5,7 @@ AnyCPU 8.0.30703 2.0 - 2e687ae0-bfc4-44af-9b34-df40da1f2c3a + {F5595B81-C00D-452E-8C4E-67380224EE4E} Library Properties PetStore.Infrastructure.NHibernate @@ -31,8 +31,27 @@ 4 + + ..\..\libs\Castle.Core.dll + + + ..\..\libs\HibernatingRhinos.Profiler.Appender.v4.0.dll + + + ..\..\libs\Iesi.Collections.dll + + + ..\..\libs\NHibernate.dll + + + ..\..\libs\NHibernate.ByteCode.Castle.dll + + + ..\..\libs\NHibernate.Caches.SysCache.dll + + @@ -40,9 +59,17 @@ - + + + + + + {FF79E5EE-F489-4239-B935-DA2C06848BFA} + PetStore.Core + +