определяя NHibernate ISession в порожденной теме с помощью NInject - PullRequest
2 голосов
/ 12 июля 2010

Хорошо, вот сценарий.У меня есть сайт ASP.NET, который периодически создает фоновый поток для выполнения некоторых работ.выполнение потока состоит из JobRunner, который перебирает список IJobs и вызывает Execute () для каждого.JobRunner и каждый IJob создается NInject.У пары IJobs есть зависимость от IRepository .Реализация IRepository, которую я использую, предназначена для NHibernate, поэтому она имеет аргумент конструктора для ISession.До сих пор NInject возвращал ISession из ISessionFactory, ограниченную каждым запросом (InRequestScope).

Вот проблема: когда различные IJobs выполняют свою обработку (которая включает в себя сохранение в IRepository),данные никогда не сохраняются, потому что ISession.Flush () никогда не вызывается.Каждый IJob ничего не знает о реализации используемого IRepository.Кроме того, JobRunner ничего не знает о реализации IJobs, которые он выполняет.Для остальной части веб-приложения это работает нормально, потому что ISession.Flush () вызывается в Application_EndRequest.

Я попытался поместить ISession в качестве аргумента конструктора для JobRunner, чтобы я мог вызвать Flush () для негокогда все IJobs завершают обработку, но кажется, что он получает ISession, отличный от IJobs (вызывая session.GetHashCode () возвращает разные значения для JobRunner, но для всех IJobs это одно и то же).Я настроил NInject для области ISession на основе HttpContext, если он есть, в противном случае используйте CurrentThread.Я полагал, что, поскольку JobRunner находится в отдельном потоке, он получит ISession, ограниченный CurrentThread, и, поскольку все IJobs выполняются в том же потоке, что и JobRunner, все они должны получить тот же ISession, но это не так.

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

Пока у меня есть обходной путь - я поместил session.Flush () в качестве последней строки моего NHibernateRepository.Save (), но я не доволен этим.

1 Ответ

1 голос
/ 14 июля 2010

ну я нашел решение.мой объект JobRunner создавался в методе Application_Start файла Global.asax, и поэтому содержал этот идентификатор потока вместо идентификатора фонового потока.

Я создал класс-обертку, который принимает тип и использует NInject для создания экземпляра, и каждый раз, когда фоновый поток приходит в себя, чтобы начать обработку, он использует класс-обертку, чтобы получить экземпляр JobRunner.это создает его в соответствующем потоке, который позволяет мне получить ту же ISession, что и мой IRepository, чтобы я мог вызывать session.Flush () после завершения всех IJobs.

возможно, есть более элегантное решение, но до тех пор, это хорошо работает.

...