2009-07-13 10 views
11

Bardzo lubię pracować z NHibernate, ale zawsze używam Spring.Net.NHibernate and Structure Map

Niedawno natknąłem się na StructureMap by Jeremy Miller i naprawdę podoba mi się to lepiej niż Spring.Net. Na swojej witrynie StructureMap obiecuje on, że można razem korzystać z NHibernate i StructureMap. Niestety nie miał czasu, aby to zrobić (lub nie mogę go znaleźć).

Czy ktoś ma przykład, jak obsługiwać sesję NHibernate za pomocą StructureMap?

+0

Czuję, że to wpadam, czekałem na ten przykład. – mxmissile

+0

Związany z http://stackoverflow.com/que stions/383440/using-fluent-nhibernate-with-structuremap-or-any-iocc – Rodrigue

Odpowiedz

23

Przepraszam więc, że nie otrzymaliśmy przykładu NHibernate z przykładami StructureMap wcześniej. W końcu chciałbym opublikować go w dokumentacji StructureMap, ale najpierw potrzebuję opinii. Można zobaczyć pełny przykład na moim blogu:

http://trason.net/journal/2009/10/7/bootstrapping-nhibernate-with-structuremap.html

Powiedział, że mogę trafić podkreśla tutaj. Istnieje NHibernateRegistry, która udostępnia cztery rzeczy: NHibernate.Configuration (jako Singleton), ISessionFactory (jako Singleton), ISession (zakresowy Hybrid (HttpContext, jeśli dostępny, wraca do lokalnego magazynu Thread)) i bardzo prosta IUnitOfWork. Ponadto istnieje HttpModule do zarządzania UnitOfWork na żądanie sieci.

Oto kod na NHibernateRegistry:

using NHibernate; 
using NHibernate.ByteCode.Castle; 
using NHibernate.Cfg; 
using NHibernate.Dialect; 
using NHibernate.Driver; 
using NHibernateBootstrap.Core.Domain; 
using StructureMap.Attributes; 
using StructureMap.Configuration.DSL; 
using Environment=NHibernate.Cfg.Environment; 

namespace NHibernateBootstrap.Core.Persistence 
{ 
    public class NHibernateRegistry : Registry 
    { 
     public NHibernateRegistry() 
     { 
      var cfg = new Configuration() 
       .SetProperty(Environment.ReleaseConnections, "on_close") 
       .SetProperty(Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName) 
       .SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName) 
       .SetProperty(Environment.ConnectionString, "data source=bootstrap.sqlite;Version=3") 
       .SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName) 
       .AddAssembly(typeof(Blog).Assembly); 

      var sessionFactory = cfg.BuildSessionFactory(); 

      ForRequestedType<Configuration>().AsSingletons().TheDefault.IsThis(cfg); 

      ForRequestedType<ISessionFactory>().AsSingletons() 
       .TheDefault.IsThis(sessionFactory); 

      ForRequestedType<ISession>().CacheBy(InstanceScope.Hybrid) 
       .TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession()); 

      ForRequestedType<IUnitOfWork>().CacheBy(InstanceScope.Hybrid) 
       .TheDefaultIsConcreteType<UnitOfWork>(); 

       ForRequestedType<IDatabaseBuilder>().TheDefaultIsConcreteType<DatabaseBuilder>(); 
     } 
    } 
} 

Oto kod na jednostkę pracy:

using System; 
using NHibernate; 

namespace NHibernateBootstrap.Core.Persistence 
{ 
    public interface IUnitOfWork : IDisposable 
    { 
     ISession CurrentSession { get; } 
     void Commit(); 
    } 
} 

using NHibernate; 

namespace NHibernateBootstrap.Core.Persistence 
{ 
    public class UnitOfWork : IUnitOfWork 
    { 
     private readonly ISessionFactory _sessionFactory; 
     private readonly ITransaction _transaction; 

     public UnitOfWork(ISessionFactory sessionFactory) 
     { 
      _sessionFactory = sessionFactory; 
      CurrentSession = _sessionFactory.OpenSession(); 
      _transaction = CurrentSession.BeginTransaction(); 
     } 

     public ISession CurrentSession { get; private set;} 

     public void Dispose() 
     { 
      CurrentSession.Close(); 
      CurrentSession = null; 
     } 

     public void Commit() 
     { 
      _transaction.Commit(); 
     } 
    } 
} 

Oto NHibernateModule dla aplikacji internetowych:

using System; 
using System.Web; 
using NHibernateBootstrap.Core.Persistence; 
using StructureMap; 

namespace NHibernateBootstrap.Web 
{ 
    public class NHibernateModule : IHttpModule 
    { 
     private IUnitOfWork _unitOfWork; 

     public void Init(HttpApplication context) 
     { 
      context.BeginRequest += ContextBeginRequest; 
      context.EndRequest += ContextEndRequest; 
     } 

     private void ContextBeginRequest(object sender, EventArgs e) 
     { 
      _unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>(); 

     } 

     private void ContextEndRequest(object sender, EventArgs e) 
     { 
      Dispose(); 
     } 

     public void Dispose() 
     { 
      _unitOfWork.Dispose(); 
     } 
    } 
} 
+1

Ale czy nie blokujesz bazy danych dla całego żądania z tym? Mam na myśli, że rozpoczynasz transakcję po rozpoczęciu żądania i zatwierdzasz ją po jej zakończeniu. – chester89

0
  • Edit tutaj: Napisałem ten komentarz przed odpowiedzią wbinford została wysłana. Nadal uważam, że używanie NCommon jest dobre, ale jego odpowiedź powyżej jest nieco czystsza i nie wymaga użycia innego narzędzia innej firmy.

Naprawdę nie dostałem odpowiedzi, których szukałem, ale znalazłem fajny framework o nazwie NCommon. Implementuje wzór jednostki pracy wraz z wzorcem repozytorium za pomocą NHibernate, LinqToSql lub Entity Framework. Obsługiwano także usługę NHibernate ISession, a także konfigurację NHibernate. Użyłem narzędzia z StructureMap i NHibernate. Musiałem uzyskać adapter usługi dla StructureMap, ale po skonfigurowaniu działa raczej ładnie.

+0

Hi dionysus55, Próbuję do nas NCommon z mapą struktury i jestem całkowicie zagubiony. Czy masz przykładowy kod pokazujący, jak to zrobić? – Todd

+0

Przepraszam, że nie mam nic, co mógłbym wydać. Jeśli spojrzysz na odpowiedź Wbinforda, podsumowuje ten proces. Adres URL, na który wskazuje, również pomaga. – dionysus55