2017-01-20 26 views
1

我有一个ASP.NET MVC应用程序,它使用Quartz运行几个计划作业。如何管理ASP.NET MVC和Quartz使用的对象的Ninject作用域绑定?

该项目使用实体框架与存储库模式。而在我的MVC项目中,为AppContext结合和GenericRepositoryInRequestScope

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>(); 

太好了!这应该工作....

不,因为被注入GenericRepositoryAppContext仍然会在RequestScope,所以我需要AppContext条件结合得。但是怎么样?我不能这样做WhenInjectedInto,因为AppContext将始终注入GenericRepository

有什么想法?或者如果有更好的方式来管理MVC应用程序中的Quartz作业范围,请分享:)

+0

向Quartz提供'IGenericRepositoryFactory',并使用'using'语句将存储库的寿命作为局部变量进行管理。 – spender

+0

即时对不起,但你能详细说明这种方法吗?谢谢! –

回答

1

Ninject提供了一个通用的InScope()方法,您可以使用该方法返回您自己定义范围的自定义对象。我过去曾经用它来首先尝试解决Request范围,如果没有,则返回当前的Thread作为范围。这样你就有了一种“混合”范围。

+0

对于迟回复戴夫,我感到抱歉。但考虑一下它能够解决请求范围(依赖于'HttpContext.Current'我相信)的场景,然而在作业执行期间请求结束了('HttpContext'被处置),即使作业可能是仍在运行。那么会发生什么? –

+0

'HttpContext.Current'在内部使用一个'LogicalCallContext',它将HttpContext存储在一个“逻辑”线程存储中(与严格的线程存储不同,它在异步任务中流动),从创建它的线程保留HttpContext。所以如果Quartz创建作业,即使在同一个进程中有活动的Web请求,也不会有一个。否则,同一个进程中的多个请求会覆盖'HttpContext.Current'。 –

+0

感谢Dave,我一直以错误的方式理解HttpContext。现在它变得更有意义,你的回答将完美地解决我的问题。谢谢! –

相关问题