Я позволяю 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
Management в HttpModule
добавляет ненужные накладные расходы, так как дает HttpContext знание о ISession
, и это означает, что я должен сделать какую-то инъекцию в HttpRequest
(которую я можно использовать [Inject]
, но это не кажется разумным)
Это привело меня к такому выводу.
- Транзакции должны начинаться при запросе
ISession
.
- Все, что происходит в одном запросе , инкапсулируется в one
ISession
- Когда
ITransaction
выполнен, его необходимо зафиксировать, чтобы кэш 2-го уровня мог получить свои результаты.
Кто-нибудь может пролить свет на это? Я, наконец, на правильном пути? Или я до сих пор полностью упустил суть?