2015-04-14 2 views
0

В настоящее время я застрял в NHibernate, и я пытаюсь определить, как правильно правильно создавать свои репозитории при правильном управлении временем жизни сеанса.Как управлять сеансами NHibernate при использовании репозиториев/транзакций

Из примеров, которые я видел, кажется, обычная практика, чтобы впрыснуть в ISession в каждом из хранилищ следующим образом:

public class SomeRepository : IRepository 
{ 
    private readonly ISession _session; 

    public SomeRepository(ISession session) 
    { 
     _session = session; 
    } 

    public IList<T> LoadSomeData() 
    { 
     return _session.Query<T>().Where(...).ToList(); 
    } 
} 

Так что это хорошо, но я могу видеть несколько случаев, где есть будут проблемы:

1) Возможно, не будет 1 сеанса на всю жизнь приложения.

2) При доступе к NHibernate мы всегда должны переносить наши вызовы в транзакцию - если транзакция не работает, мы должны отменить транзакцию и закрыть сеанс.

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

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

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

1) Перестройте репозитории (и создайте новый сеанс) каждый раз, когда процессу необходимо выполнить некоторую работу БД.

2) Внесите репозитории с помощью SessionFactory. Затем репозиторий предоставляет этот SessionFactory. Затем пользователь каждого репозитория открывает новый сеанс одновременно с началом транзакции.

3) Создайте класс UnitOfWork, который вводится в репозитории и отвечает за управление сроками службы сеанса & Сделки. При каждом вызове в репозиторий происходит вызов в UnitOfWork, который создает совершенно новый сеанс, и вызов выполняется в транзакции. Поэтому хранилища не знают о сеансах/транзакциях.

Для меня 3) кажется лучшим решением, и я видел несколько примеров этого онлайн, но во всех примерах они создают только 1 сеанс в UnitOfWork, и они не воссоздают его, если транзакция откат.

Кроме того, ограничение с 3) заключается в том, что UnitOfWork привязан к определенному репозиторию, и поэтому у вас не могло быть транзакции, которая вызывала вызовы в разные Хранилища.

Надеюсь, что имеет смысл и будет признателен за любое руководство.

Благодаря

ответ

1

Собственно сессия в NHibernate можно использовать в качестве UnitOfWork. Но если вы хотите использовать этот шаблон, вот реализация: http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html.

Но, однако, лучшим решением в вашем списке является 1. Таким образом, вам нужно создавать сеансы и хранилища каждый раз, когда вам нужно сделать работу с БД.

Использование UnitOfWork он будет выглядеть так:

using(var uow = new UnitOfWork()) 
{ 
    var rep1 = new SomeRepository1(uow); 
    rep1.DoSomeJob(); 

    var rep2 = new SomeRepository2(uow); 
    rep2.DoSomeOtherJob(); 
} 

Использование родного ISession:

using(var session = SessionFactory.OpenSession()) 
using(var tr = session.BeginTransaction()) 
{ 
    var rep1 = new SomeRepository1(session); 
    rep1.DoSomeJob(); 

    var rep2 = new SomeRepository2(session); 
    rep2.DoSomeOtherJob(); 

    tr.Commit(); 
} 

Также вы можете использовать силу DI/IoC контейнеры для управления жизни сессий.

Если вас интересует последний вариант, я могу показать вам пример.

+0

Спасибо за ответ, я в конце концов обнял его и пошел с чем-то похожим на то, что вы отправили, в результате чего я создаю новый UnitOfWork, который отвечает за открытие нового сеанса и управление транзакцией. Сеанс из этого UnitOfWork затем используется для создания репозиториев. Затем UoW удаляется после совершения транзакции, которая закрывает сеанс. – Chris

+0

Хорошо. Но в моих приложениях я иду другим путем: 1. Я реализую транзакцию бизнеса, которая управляет вложенными транзакциями. 2. Я использую шаблон [http://en.wikipedia.org/wiki/Active_record_pattern] (ActiveRecord). –

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