2015-03-24 6 views
6

Ich versuche, UnitOfWork und Repository-Muster mit NHibernate zu implementieren. Ich bin auf der Suche nach der besten Möglichkeit, Sitzung zwischen Einheit der Arbeit und Repository-Instanz zu teilen.Teilen einer NHibernate-Sitzung zwischen UnitOfWork und Repository

Der offensichtlichste Weg ist ThreadStatic Eigenschaften in UnitOfWork Klasse

public class UnitOfWork : IUnitOfWork 
{ 
    public static UnitOfWork Current 
    { 
     get { return _current; } 
     set { _current = value; } 
    } 
    [ThreadStatic] 
    private static UnitOfWork _current; 

    public ISession Session { get; private set; } 

    //other code 
} 

Und dann in Repository Klasse vorstellen:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class 
{ 
    protected ISession Session { get { return UnitOfWork.Current.Session; } } 

    //other code 
} 

Allerdings möchte ich Implementierung oben und beschlossen aufgeführt nicht zu finde einen anderen Weg, das Gleiche zu tun. So

Ich kam mit dem zweiten Weg:

public interface ICurrentSessionProvider : IDisposable 
{ 
    ISession CurrentSession { get; } 
    ISession OpenSession(); 
    void ReleaseSession(); 
} 

public class CurrentSessionProvider : ICurrentSessionProvider 
{ 
    private readonly ISessionFactory _sessionFactory; 

    public CurrentSessionProvider(ISessionFactory sessionFactory) 
    { 
     _sessionFactory = sessionFactory; 
    } 

    public ISession OpenSession() 
    { 
     var session = _sessionFactory.OpenSession(); 
     CurrentSessionContext.Bind(session); 
     return session; 
    } 

    public void Dispose() 
    { 
     CurrentSessionContext.Unbind(_sessionFactory); 
    } 

    public ISession CurrentSession 
    { 
     get 
     { 
      if (!CurrentSessionContext.HasBind(_sessionFactory)) 
      { 
       OnContextualSessionIsNotFound(); 
      } 
      var contextualSession = _sessionFactory.GetCurrentSession(); 
      if (contextualSession == null) 
      { 
       OnContextualSessionIsNotFound(); 
      } 
      return contextualSession; 
     } 
    } 

    private static void OnContextualSessionIsNotFound() 
    { 
     throw new InvalidOperationException("Session is not opened!"); 
    } 
} 

wo ISessionFactory Singleton von Autofac aufgelöst wird und CurrentSessionContextCallSessionContext ist. Dann injiziere ich ICurrentSessionProvider in Konstruktoren UnitOfWork und Repository Klassen und verwenden Sie CurrentSession Eigenschaft, Sitzungen zu teilen.

Beide Ansätze scheinen gut zu funktionieren. Ich frage mich also, gibt es andere Möglichkeiten, dies zu implementieren? Was ist die beste Vorgehensweise beim Teilen der Sitzung zwischen Arbeitseinheit und Repository?

Antwort

0

Der beste Weg, dies zu tun, wäre, die Vorteile zu nutzen, die NHibernate bereits zu diesem Zweck bietet. schauen Sie bitte in Abschnitt auf der folgenden Dokumentation „2.3 Kontext-bezogene Sessions.“: http://nhibernate.info/doc/nh/en/#architecture-current-session

Grundsätzlich benötigen Sie:

  1. Eine geeignete Implementierung der ICurrentSessionContext Schnittstelle, die Ihren Bedürfnissen gerecht wird.
  2. Informieren Sie die SessionFactory, dass Sie diese Implementierung verwenden möchten.
  3. Inject ISessionFactory (Ihre Sitzungsfabrik) an jeden Ort, an dem Sie auf die "aktuelle Sitzung" zugreifen müssen.
  4. Beziehen Sie die aktuelle Sitzung mit sessionFactory.GetCurrentSession().

Dies hat den Vorteil, dass Sie Ihre Session-Handling-Strategie mit kompatibel sein wird, wie es von den meisten NHibernate Projekte getan werden sollte, und es hängt nicht alles an den Orten, neben einem ISessionFactory auf Haben Sie die aktuelle Sitzung zugreifen möchten .

Vergessen zu erwähnen: Sie können natürlich Ihren eigenen ICurrentSessionContext basierend auf dem Code implementieren, den Sie bereits in Ihrer Frage aufgelistet haben.

+0

Ich hoffe, Sie könnten ein Codebeispiel für die Einstellung dieser bestimmten Architektur bereitstellen! – adaam

+0

Hey, ich bin gerade in Eile, aber vielleicht hilft dir das folgende, sehr vereinfachte Beispiel (ich werde sehen, ob ich es später aktualisieren kann): https://gist.github.com/anonymous/ ebd36d4a39c2ed45dd20824d849f89f7 –

Verwandte Themen