Я использую Castle Windsor 3.0 для инъекций зависимостей в демонстрационном приложении ASP.NET. Один из моих контроллеров принимает экземпляр ICustomerService, который, в свою очередь, принимает экземпляр ISession, все через конструктор. ISession зарегистрирован в Windsor с использованием заводского метода и стиля жизни PerWebRequest.Сделка исчезает при использовании windsor + nhibernate
_container.Register(Component.For<ISessionFactory>().Instance(DbHelper.BuildSessionFactory()).LifestyleSingleton());
_container.Register(Component.For<ISession>().LifestylePerWebRequest().UsingFactoryMethod(x => x.Resolve<ISessionFactory>().OpenSession()));
В файле global.asax, у меня есть обработчик Application_EndRequest, который пытается совершить сделку:
protected void Application_EndRequest(object sender, EventArgs e)
{
if (!IsStaticResourceRequest())
{
var app = (HttpApplication)sender;
var factory = _container.Resolve<ISessionFactory>();
var session = ManagedWebSessionContext.Unbind(Context, factory);
if (session != null &&
session.Transaction != null &&
session.Transaction.IsActive)
{
session.Transaction.Commit();
session.Transaction.Dispose();
session.Dispose();
}
}
}
Проблема заключается в том, что PerWebRequest образ жизни Виндзор имеет свой собственный обработчик события Application_EndRequest который распоряжается службы до моего обработчика Application_EndRequest (в global.asax), поэтому код в моем обработчике Application_EndRequest никогда не получает возможности совершить транзакцию. Есть ли обходной путь для этого?
Это может работать для простых изолированных случаев, но представьте себе действие контроллера, которое вызывает несколько служб или обращается к нескольким репозиториям через их отдельную (но идентичную для каждого запроса веб-запроса) ссылку на сеанс. Вы не можете иметь более одной активной транзакции за сеанс. – Chris
Привет Крис. Я использую это только для «простых изолированных случаев». Тот же сеанс используется повторно, так как Windosor вернет тот же сеанс для срока службы запроса. Мой комментарий был больше о том, как долго вы хотите открывать транзакции и где вы хотите совершить транзакции. Также становится более сложным показывать сообщения об ошибках клиентам, когда вы полагаетесь на транзакции, которые должны быть совершены в конце запроса. Я предпочитаю обрабатывать ошибки в контроллере и отображать соответствующие сообщения клиенту. – Chev