2015-03-24 31 views
6

NHibernate ile UnitOfWork ve Repository desenlerini uygulamaya çalışıyorum. Birimi, çalışma birimi ve depo örneği arasında paylaşmanın en iyi yolunu arıyorum.UnitOfWork ve Deposu arasında NHibernate oturumu paylaşma

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

    //other code 
} 

Ancak uygulama yukarıda listelenen ve karar gibi değildi:

en açık yoluRepository sınıfında UnitOfWork sınıfında sonra

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 
} 

Ve ThreadStatic özelliklerini tanıtmak aynısını yapmak için başka bir yol bulmak.

yüzden ikinci yolu ile geldi: ISessionFactory tekil AutoFac çözülmektedir

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!"); 
    } 
} 

ve CurrentSessionContextCallSessionContext olduğunu. UnitOfWork ve Repository sınıfları yapıcılarına ICurrentSessionProvider enjekte edip oturumları paylaşmak için CurrentSession özelliğini kullanın.

Her iki yaklaşım da iyi çalışıyor gibi görünüyor. Bu yüzden bunu uygulamak için başka yollar var mı merak ediyorum? Çalışma birimi ile depo arasındaki oturumda en iyi uygulama nedir?

cevap

0

Bunu yapmanın en iyi yolu, bu etkiyi zaten sağlayan NHibernate tesislerinden yararlanmak olacaktır. bölümüne bakınız aşağıdaki belgeler üzerinde "2.3 Bağlamsal Oturumları.": http://nhibernate.info/doc/nh/en/#architecture-current-session

Temel olarak, gerek:

  1. ihtiyaçlarınızı karşılar ICurrentSessionContext arayüzünün uygun bir uygulama.
  2. Bu uygulamayı kullanmak istediğiniz SessionFactory'yi bilgilendirin.
  3. ISessionFactory'yi (oturumunuzun fabrikasını) "geçerli oturuma" erişmeniz gereken herhangi bir yere enjekte edin.
  4. Geçerli oturumu sessionFactory.GetCurrentSession() kullanarak elde edin.

Bu sizin oturum yönetimi stratejisi çoğu NHibernate projeleri yapılmalı nasıl uyumlu olacak bir avantaja sahiptir ve geçerli oturumu erişmek istediğiniz yerlerde bir ISessionFactory dışında bir şey olması bağlı değildir .

Unutmayın: Elbette kendi ICurrentSessionContext dosyanızı sorgunuzda listelediğiniz kodlara göre uygulayabilirsiniz.

+0

Bu mimariyi ayarlamak için bir kod örneği sağlayabileceğinizi umuyordum! – adaam

+0

Hey, şu anda acelem var, ama belki de aşağıdaki çok basitleştirilmiş örnek başlamanıza yardımcı olabilir (daha sonra güncelleyebilir miyim göreceksiniz): https://gist.github.com/anonymous/ ebd36d4a39c2ed45dd20824d849f89f7 –