2017-01-20 18 views
1

У меня есть приложение ASP.NET MVC, которое запускает несколько запланированных заданий с Quartz.Как управлять привязкой области Ninject для объектов, используемых как ASP.NET MVC, так и Quartz?

В проекте используется структура Entity Framework с шаблоном репозитория. И в моем проекте MVC, связывание для AppContext и GenericRepository являются InRequestScope:

Bind<AppContext>().ToSelf().InRequestScope(); 
Bind<IGenericRepository>().To<GenericRepository>().InRequestScope(); 

GenericRepository принимает AppContext в качестве аргумента конструктора, и обзорное здесь имеет смысл для проекта MVC. Однако контекст и репозиторий также используются некоторыми заданиями Quartz, и, очевидно, вышеуказанная область не будет работать для задания Quartz. Например:

public class SampleJob : IJob 
{ 
    public SampleJob(IGenericRepository repository) 
    { 
     // some code... 
    } 
} 

Здесь мне нужно вводить IGenericRepository с другой области, возможно, InThreadScope(). И я могу сделать это с помощью условного связывания IGenericRepository следующим образом:

Bind<IGenericRepository>() 
    .To<GenericRepository>() 
    .InThreadScope() 
    .WhenInjectedInto<SampleJob>(); 

Отлично! Это должно работать ....

Нет, потому что AppContext, который вводится в GenericRepository еще будет в RequestScope, так что мне нужно условное связывание для AppContext тоже. Но как?? Я не могу сделать WhenInjectedInto, потому что AppContext всегда будет вводиться в GenericRepository.

Любая идея? Или, если есть лучший способ управлять областями работы Quartz в приложении MVC, пожалуйста, делите :)

+0

Предоставьте «IGenericRepositoryFactory» стороне кварца и управляйте жизненным циклом хранилища как локальной переменной с помощью операторов 'using'. – spender

+0

им жаль, но не могли бы вы подробнее рассказать об этом подходе? благодаря! –

ответ

1

Ninject предоставляет общий метод InScope(), который вы можете использовать для возврата собственного пользовательского объекта, который определяет область действия. Я использовал это в прошлом, чтобы сначала попытаться разрешить область запроса, а если ее нет, верните текущий поток как область видимости. таким образом у вас есть своего рода «гибридная» область.

+0

Прошу прощения за поздний ответ Дэйва. Но рассмотрим сценарий, в котором он смог разрешить область запроса (которая зависит от 'HttpContext.Current', я полагаю), однако во время выполнения задания завершение запроса (' HttpContext'), хотя задание может быть Все еще работает. что тогда будет? –

+0

'HttpContext.Current' внутренне использует' LogicalCallContext', который хранит HttpContext в «логическом» хранилище потоков (который, в отличие от жесткого хранилища потоков, протекает через задачи async), сохраняет HttpContext из потока, который его создал. поэтому, если Quartz создает задание, их не будет, даже если есть активные веб-запросы в одном и том же процессе. в противном случае несколько запросов в том же процессе переписывали бы «HttpContext.Current». –

+0

Спасибо Дэйву, все это время я понял HttpContext неправильно. Теперь это имеет гораздо больший смысл, и ваш ответ решит мою проблему отлично. Благодаря! –