在我的解决方案中,我使用EF与存储库模式和我的主要Web项目中的Ninject来解决控制器依赖关系,我还有一个管理Quartz作业的Job项目 - 将Ninject与Quartz链接的正确方法是什么,以便EF将工作?
我知道我需要实现自定义JobFactory,所以我在Job项目中创建了以下内容:
public class NinjectJobFactory : IJobFactory
{
private readonly IKernel resolutionRoot;
public NinjectJobFactory(IKernel resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return (IJob)this.resolutionRoot.Get(bundle.JobDetail.JobType);
}
public void ReturnJob(IJob job)
{
string dud = "";
}
}
为了初始化石英作业,我执行以下操作:
然后在JobManager中,我添加作业并运行这样的调度程序:
public void Start()
{
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sched = sf.GetScheduler();
sf.GetScheduler().JobFactory = new NinjectJobFactory(ninjectKernel);
DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTime.UtcNow);
DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(null, 10);
IJobDetail job = JobBuilder.Create<CheckIfAllSaleActionDataIsValid>()
.WithIdentity("CheckIfAllSaleActionDataIsValid", "HostessStatJobs")
.Build();
job.JobDataMap.Add("SiteUrl", SiteUrl);
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("CheckIfAllSaleActionDataIsValidTrigger", "HostessStatJobTriggers")
.StartAt(startTime)
.WithCronSchedule("0 0 0/1 1/1 * ? *")
.Build();
sched.ScheduleJob(job, trigger);
IJobDetail job2 = JobBuilder.Create<CheckPaymentAndAssigneRoles>()
.WithIdentity("CheckPaymentAndAssigneRoles", "HostessStatJobs")
.Build();
job2.JobDataMap.Add("commonMethods", ninjectKernel.Get<CommonMethods>());
ITrigger trigger2 = TriggerBuilder.Create()
.WithIdentity("CheckPaymentAndAssigneRolesTrigger", "HostessStatJobTriggers")
.StartAt(startTime)
.WithCronSchedule("0 0/1 * 1/1 * ? *")
.Build();
sched.ScheduleJob(job2, trigger2);
sched.Start();
}
问题是由NinjectJobFactory生成的每个对象的DbContext是不同的,因此我不能使用EF(我得到:实体对象不能被IEntityChangeTracker的多个实例引用,这是可以理解的我的存储库中的每个对象都引用了不同的DbContext)。
奇怪的是 - 如果我手动调用 NinjectKernel.Get(); - 例如 - 在Global.asax中我可以清楚地看到单个上下文被传递 - 应该是这样。
我的上下文在我的Ninjectresolver中绑定如下: ninjectKernel.Bind()。ToSelf()。InRequestScope(); - 这可能是问题吗?
问题是:
编辑:
对于迟到的回复感到抱歉,看起来InRequestScope实际上是问题 - 我在QuartzJobs子项目中创建了单独的ninject内核,并且:
问题是 - 它不会破坏我的数据库吗?据我了解,建议为每个用户请求使用新的DbContext以避免数据库死锁 - 如果我错了就纠正我,但是对于Quartz作业项目来说没有必要吗?我的意思是 - 这个项目总是使用单一连接,所以它不应该死锁数据库吗?
我说错了吗?如果不是 - 每次运行Job时注入不同DbContext的正确方法是什么? InRequestScope不能在MVC项目之外工作......