В настоящее время я застрял в 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 привязан к определенному репозиторию, и поэтому у вас не могло быть транзакции, которая вызывала вызовы в разные Хранилища.
Надеюсь, что имеет смысл и будет признателен за любое руководство.
Благодаря
Спасибо за ответ, я в конце концов обнял его и пошел с чем-то похожим на то, что вы отправили, в результате чего я создаю новый UnitOfWork, который отвечает за открытие нового сеанса и управление транзакцией. Сеанс из этого UnitOfWork затем используется для создания репозиториев. Затем UoW удаляется после совершения транзакции, которая закрывает сеанс. – Chris
Хорошо. Но в моих приложениях я иду другим путем: 1. Я реализую транзакцию бизнеса, которая управляет вложенными транзакциями. 2. Я использую шаблон [http://en.wikipedia.org/wiki/Active_record_pattern] (ActiveRecord). –