Я разрешаю Ninject управлять состоянием ISession
и ITransaction
в Fluent nHibnerate со следующим методом регистрации - мне интересно, достаточно ли контролировать транзакции или нужно ли это помещать в другое место.
Мысль о том, что каждый ISession
создается по запросу и что Ninject обрабатывает фиксацию всего, что было сделано во время этого запроса.
public class SessionModule : Ninject.Modules.NinjectModule
{
private static ISessionFactory sessionFactory;
public override void Load()
{
Bind<ISessionFactory>()
.ToMethod(c => CreateSessionFactory())
.InSingletonScope();
Bind<ISession>()
.ToMethod(c => OpenSession())
.InRequestScope()
.OnActivation(session =>
{
session.BeginTransaction();
session.FlushMode = FlushMode.Commit;
})
.OnDeactivation(session =>
{
if (session.Transaction.IsActive)
{
try
{
session.Flush();
session.Transaction.Commit();
}
catch
{
session.Transaction.Rollback();
}
}
});
}
/// <summary>
/// Create a new <see cref="NHibernate.ISessionFactory"/> to connect to a database.
/// </summary>
/// <returns>
/// A constructed and mapped <see cref="NHibernate.ISessionFactory"/>.
/// </returns>
private static ISessionFactory CreateSessionFactory()
{
if (sessionFactory == null)
sessionFactory = Persistence.SessionFactory.Map
(System.Web.Configuration
.WebConfigurationManager
.ConnectionStrings["Local"]
.ConnectionString
);
return sessionFactory;
}
/// <summary>
/// Open a new <see cref="NHibernate.ISession"/> from a <see cref="NHibernate.ISessionFactory"/>.
/// </summary>
/// <returns>
/// A new <see cref="NHibernate.ISession"/>.
/// </returns>
private static ISession OpenSession()
{
// check to see if we even have a session factory to get a session from
if (sessionFactory == null)
CreateSessionFactory();
// open a new session from the factory if there is no current one
return sessionFactory.OpenSession();
}
}
Я просмотрел среду выполнения, используя System.Diagnostics.Debug.WriteLine
, чтобы писать, когда что-то происходит, и она делает, как будто это делает то, что я хотел делать. То, о чем я прошу вас, сообщество, является ли это практикой хорошей или нет. Вот мое понимание.
Бесчисленные часы чтения на http://ayende.com/blog/default.aspx привели меня к переоценке большого количества способов управления сеансами.
Многое вникание в документацию nHibernate говорит мне, что мне нужно использовать ITransaction
каждый раз, когда что-либо происходит с моей базой данных.
Размещение управления в атрибуте считается недостатком, поскольку оно не соответствует указанному выше утверждению.
Выполнение ITransaction
для каждой операции не является правильным процессом, поскольку для управления (A) мои контроллеры требуется доступ к ISession
или (B) My IRepository<T>
, чтобы иметь логику ITransaction
о чем я говорил в предыдущих вопросах, не было хорошей практикой.
Размещение моего ITransaction
Менеджмента в HttpModule
добавляет ненужные служебные данные, поскольку это дает мне знание HttpContext ISession
, и это означает, что я должен сделать какую-то инъекцию в HttpRequest
(который я может использовать [Inject]
, но это не кажется мудрым)
Это привело меня к такому выводу.
- Транзакции должны начинаться с запроса
ISession
. - Все, что происходит в одиночном запросе, инкапсулируется одним
ISession
- Когда выполняется
ITransaction
, его необходимо выполнить так, чтобы 2-й уровень кэша мог получить свои результаты.
Может ли кто-нибудь пролить свет на это? Неужели я, наконец, на правильном пути? Или я все еще пропустил это?