using System; using System.IO; using System.Collections; using System.Text; using System.Xml; using System.Reflection; using NHibernate; using NHibernate.Cache; using System.Web; using log4net; using log4net.Config; namespace SV01.Library.AUM { /// /// Handles creation and management of sessions and transactions. It is a singleton because /// building the initial session factory is very expensive. Inspiration for this class came /// from Chapter 8 of Hibernate in Action by Bauer and King. Although it is a sealed singleton /// you can use TypeMock (http://www.typemock.com) for more flexible testing. /// internal sealed class NHibernateSessionManager { #region Thread-safe, lazy Singleton /// /// This is a thread-safe, lazy singleton. See http://www.yoda.arachsys.com/csharp/singleton.html /// for more details about its implementation. /// public static NHibernateSessionManager Instance { get { return Nested.nHibernateSessionManager; } } /// /// Initializes the NHibernate session factory upon instantiation. /// private NHibernateSessionManager() { InitSessionFactory(); } /// /// Assists with ensuring thread-safe, lazy singleton /// private class Nested { static Nested() { } internal static readonly NHibernateSessionManager nHibernateSessionManager = new NHibernateSessionManager(); } #endregion private void InitSessionFactory() { LoggingManager.Instance.Debug("start init NHibernate session factory"); NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration(); Stream stream = null; try { stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(this.GetType(), "hibernate.cfg.xml"); if (stream == null) throw new ApplicationException("NHibernate configuration not found!"); cfg.Configure(new XmlTextReader(stream)); sessionFactory = cfg.BuildSessionFactory(); } finally { if (stream != null) stream.Close(); } LoggingManager.Instance.Debug("end init NHibernate session factory"); } public ISession CreateSession() { return CreateSession(null); } /// /// Gets a session with or without an interceptor. This method is not called directly; instead, /// it gets invoked from other public methods. /// private ISession CreateSession(IInterceptor interceptor) { ISession session; if (interceptor != null) { session = sessionFactory.OpenSession(interceptor); } else { session = sessionFactory.OpenSession(); } return session; } public void CloseSession(ISession session) { if (session != null && session.IsOpen) { session.Close(); } } private ISessionFactory sessionFactory; } }