我正在尝试让Quartz.net(2.1.2)使用IoC容器(autofac),因为我需要在预定的作业中使用服务。我在这个主题上找到了类似的帖子,但我似乎找不到一个具有autofac特定注册示例的帖子。
以下文章涉及我遇到的同一问题:
How to schedule task using Quartz.net 2.0?
然而,我相信我缺少的部分是答案说“并且不要忘记在IoC容器中注册作业”。我不确定如何做到这一点,因为到目前为止我所尝试的一切都没有用。
在下面的示例中,“HelloJob”将运行,但每当我尝试将releaseService注入“ReleaseJob”时,它都拒绝运行。
更新 我在DependencyRegistration.cs部分标记了代码,我认为问题在于。
更新2: 一些相关的链接与我需要做的事情有关并可能有所帮助(我已经完成了所有这些但仍无法弄清楚如何使用autofac):
如何以PRO方式使用Quartz.NET? - http://blog.goyello.com/2009/09/21/how-to-use-quartz-net-in-pro-way/
Autofac和Quartz.NET - http://blog.humann.info/post/2013/01/30/Autofac-and-QuartzNET.aspx
Quartz.NET和Simple Injector的构造函数注入 - Constructor injection with Quartz.NET and Simple Injector
ASP.Net MVC 3,Ninject和Quartz.Net - 如何? - ASP.Net MVC 3, Ninject and Quartz.Net - How to?
以下是相关代码:
Global.asax中
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
var dependencyRegistration = new DependencyRegistration();
dependencyRegistration.Register();
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(new ValidatorFactory()));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
}
DependencyRegistration.cs
public class DependencyRegistration
{
public void Register()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
// Validation
builder.RegisterType<ValidatorFactory>()
.As<IValidatorFactory>()
.InstancePerHttpRequest();
AssemblyScanner findValidatorsInAssembly = AssemblyScanner.FindValidatorsInAssembly(Assembly.GetExecutingAssembly());
foreach (AssemblyScanner.AssemblyScanResult item in findValidatorsInAssembly)
{
builder.RegisterType(item.ValidatorType)
.As(item.InterfaceType)
.InstancePerHttpRequest();
}
// Schedule
builder.Register(x => new StdSchedulerFactory().GetScheduler()).As<IScheduler>();
// Schedule jobs
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(x => typeof(IJob).IsAssignableFrom(x));
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
//Schedule
IScheduler sched = container.Resolve<IScheduler>();
sched.JobFactory = new AutofacJobFactory(container);
sched.Start();
IJobDetail job = JobBuilder.Create<ReleaseJob>()
.WithIdentity("1Job")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("1JobTrigger")
.WithSimpleSchedule(x => x
.RepeatForever()
.WithIntervalInSeconds(5)
)
.StartNow()
.Build();
sched.ScheduleJob(job, trigger);
job = JobBuilder.Create<HelloJob>()
.WithIdentity("2Job")
.Build();
trigger = TriggerBuilder.Create()
.WithIdentity("2JobTrigger")
.WithSimpleSchedule(x => x
.RepeatForever()
.WithIntervalInSeconds(5)
)
.StartNow()
.Build();
sched.ScheduleJob(job, trigger);
}
}
JobFactory.cs
public class AutofacJobFactory : IJobFactory
{
private readonly IContainer _container;
public AutofacJobFactory(IContainer container)
{
_container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return (IJob)_container.Resolve(bundle.JobDetail.JobType);
}
public void ReturnJob(IJob job)
{
}
}
ReleaseJob.cs
public class ReleaseJob : IJob
{
private readonly IReleaseService _releaseService;
public ReleaseJob(IReleaseService releaseService)
{
this._releaseService = releaseService;
}
public void Execute(IJobExecutionContext context)
{
Debug.WriteLine("Release running at " + DateTime.Now.ToString());
}
}
public class HelloJob : IJob
{
public void Execute(IJobExecutionContext context)
{
Debug.WriteLine("Hello job at " + DateTime.Now.ToString());
}
}
ReleaseServiceModel.cs
public class ReleaseServiceModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ReleaseService>()
.As<IReleaseService>()
.InstancePerLifetimeScope();
}
}
答案 0 :(得分:5)
我终于找到了问题所在。
我的发布服务使用的是一个使用不同范围创建的数据存储库。
我通过创建一个新的测试服务来发现这一点,该服务除了返回一个字符串之外什么也没做,而且它被注入石英作业。
发现这一点后,我更改了发布服务调用的存储库的范围,然后发布服务在quartz工作中开始工作。
我向任何看过这个问题的人道歉,试图帮助我。因为没有列出发布服务的代码,所以很难弄清楚出了什么问题。
我已经使用autofac用于石英的最终工作绑定更新了代码。
答案 1 :(得分:0)
问题是你的AutofacJobFactory没有创建ReleaseJob
(你用JobBuilder.Create<ReleaseJob>()
代替),所以IoC容器不知道它的实例化意味着不能发生依赖注入。
以下代码应该有效:
sched = schedFact.GetScheduler();
sched.JobFactory = new AutofacJobFactory(container);
sched.Start();
// construct job info
JobDetailImpl jobDetail = new JobDetailImpl("1Job", null, typeof(ReleaseJob ));
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("1JobTrigger")
.WithSimpleSchedule(x => x
.RepeatForever()
.WithIntervalInSeconds(5)
)
.StartNow()
.Build();
sched.ScheduleJob(jobDetail, trigger);
请注意,在此示例中,我们不再使用JobBuilder.Create<ReleaseJob>()
,而是通过JobDetailImpl
对象传递要创建的作业的详细信息,并通过这样做调度程序的jobfactory({{1负责实例化作业,并且可以发生依赖注入。