title: How to manage NHibernate sessions when using Repositories/Transactions
body: <p>I'm getting stuck into NHibernate at the moment and I'm trying to work out how best to correctly design my Repositories whilst correctly managing the lifetime of the Session.</p>
  
  <p>From the examples I've seen, it seems common practise to inject an ISession into each of the repositories as follows:</p>
  
  <pre><code>public class SomeRepository : IRepository
  {
      private readonly ISession _session;
  
      public SomeRepository(ISession session)
      {
          _session = session;
      }
  
      public IList&lt;T&gt; LoadSomeData()
      {
          return _session.Query&lt;T&gt;().Where(...).ToList();
      }
  }
  </code></pre>
  
  <p>So this is fine, but I can see a couple of cases where there will be problems:</p>
  
  <p>1) There may not be 1 Session for the lifetime of the app.</p>
  
  <p>2) When accessing NHibernate we should always wrap our calls in a Transaction - if the transaction faults then we must Rollback the transaction and close the Session.</p>
  
  <p>In both these cases the Repository would be defunct as it references a closed Session.</p>
  
  <p>My particular application is a long running process, which will only occasionally call into NHibernate, so I would expect a high turnover Sessions instead of keeping 1 Session open for the lifetime of the app.</p>
  
  <p>I am therefore wondering what the established pattern for dealing with this particular situation? I see several potential solutions, but it's hard to see which is the best practise:</p>
  
  <p>1) Rebuild the repositories (and create a new Session) every time the process needs to do some DB work.</p>
  
  <p>2) Inject the Repositories with a SessionFactory. The Repository then exposes this SessionFactory. The consumer of each repository then Opens a new Session at the same time as starting a transaction.</p>
  
  <p>3) Create a UnitOfWork class which is injected into the Repositories and is responsible for managing Session lifetimes &amp; Transactions. Each time a call into a Repository is made, is calls into UnitOfWork, which creates a brand new Session and the call is executed within a Transaction. The repositories therefore have no knowledge of the Sessions/Transactions.</p>
  
  <p>To me, 3) seems like the best solution, and I've seen a few examples of this online, but in all of the examples they only create 1 session within UnitOfWork, and they don't recreate it if the transaction is rolled back.</p>
  
  <p>In addition, a limitation with 3) is that the UnitOfWork is tied to a particular repository, and so you couldn't have a transaction which made calls into different Repositories.</p>
  
  <p>Hope that makes sense and would appreciate any guidance.</p>
  
  <p>Thanks</p>