2015-03-24 2 views
6

Я пытаюсь реализовать шаблон UnitOfWork и Repository с помощью NHibernate. Я ищу лучший способ обмена сеансом между экземпляром экземпляра рабочей единицы и экземпляром репозитория.Обмен сеансом NHibernate между UnitOfWork и репозиторием

Наиболее очевидным способом является введение ThreadStatic свойства в UnitOfWork класса

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 
} 

, а затем в Repository классе:

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

    //other code 
} 

Однако мне не нравится реализация перечисленных выше, и решил найти другой способ сделать то же самое.

Так я пришел со вторым способом:

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

где ISessionFactory является одноточечно разрешаться autofac и CurrentSessionContext является CallSessionContext. Затем я добавляю ICurrentSessionProvider в конструкторы классов UnitOfWork и Repository и пользуюсь свойством CurrentSession.

Оба подхода, похоже, работают нормально. Поэтому мне интересно, есть ли другие способы реализовать это? Какова наилучшая практика обмена сеансом между единицей работы и хранилищем?

ответ

0

Лучший способ для этого - воспользоваться преимуществами, которые NHibernate предоставляет для этого. Пожалуйста, смотрите раздел по следующей документации «2.3 контекстную Sessions.»: http://nhibernate.info/doc/nh/en/#architecture-current-session

В принципе, вам нужно:

  1. Подходящая реализация интерфейса ICurrentSessionContext, который удовлетворяет ваши потребности.
  2. Сообщите SessionFactory, что вы хотите использовать эту реализацию.
  3. Inject ISessionFactory (ваша фабрика сеансов) в любое место, где вам нужно получить доступ к «текущей сессии».
  4. Получить текущий сеанс с помощью sessionFactory.GetCurrentSession().

Это имеет то преимущество, что ваша стратегия обработки сеансов будет совместима с тем, как это должно быть сделано большинством проектов NHibernate, и это не зависит от наличия чего-либо помимо ISessionFactory в тех местах, где вы хотите получить доступ к текущему сеансу ,

Вспомните: Вы можете, конечно, реализовать свой собственный ICurrentSessionContext на основе кода, который вы уже указали в своем вопросе.

+0

Было надеяться, что вы можете предоставить образец кода для настройки этой конкретной архитектуры! – adaam

+0

Эй, я сейчас спешу, но, возможно, следующий очень упрощенный образец поможет вам начать работу (посмотрю, смогу ли я его обновить позже): https://gist.github.com/anonymous/ ebd36d4a39c2ed45dd20824d849f89f7 –

Смежные вопросы