如何创建一个Quartz.NET的工作,需要注射autofac
问题:
使用 Quartz.Net 做定时任务时,实现IJob对象的服务,Autofac不会自动注入,使用构造函数会直接出现异常,无法执行Execute方法。
解决方式
方法一: 使用 Autofac的Quartz.Net的扩展包
Gitbub地址: https://github.com/alphacloud/Autofac.Extras.Quartz
使用方法:
1、需要下载Autofac的扩展包,可以通过Nuget包管理工具下载
Autofac.Extras.Quartz
2、在Autofac配置文件中注册Quartz模块
//注册定时任务模块 builder.RegisterModule(new QuartzAutofacFactoryModule()); builder.RegisterModule(new QuartzAutofacJobsModule(typeof(JobTest).Assembly));
3、然后在Job任务对象中,就可以通过构造函数注入服务对象。
方法二:
因我本机的项目使用的Autofac是3.5版本,如果安装Autofac.Extras.Quartz,需要升级Autofac版本,要么用很旧的版本,方法一并不友好。
首先,在mvc根目录下新建Autofac扩展类:
1 internal static class AutofacExt 2 { 3 private static IContainer _container; 4 public static void InitAutofac() 5 { 6 var builder = new ContainerBuilder(); 7 8 //注册数据库基础操作和工作单元 9 builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IRepository<>)); 10 builder.RegisterType(typeof (UnitWork)).As(typeof (IUnitWork)); 11 12 //注册WebConfig中的配置 13 builder.RegisterModule(new ConfigurationSettingsReader("autofac")); 14 15 //注册app层 16 builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof (UserManagerApp))); 17 18 //注册领域服务 19 builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(AuthoriseService))); 20 21 // Register your MVC controllers. 22 builder.RegisterControllers(typeof(MvcApplication).Assembly); 23 24 // OPTIONAL: Register model binders that require DI. 25 builder.RegisterModelBinders(Assembly.GetExecutingAssembly()); 26 builder.RegisterModelBinderProvider(); 27 28 // OPTIONAL: Register web abstractions like HttpContextBase. 29 builder.RegisterModule<AutofacWebTypesModule>(); 30 31 // OPTIONAL: Enable property injection in view pages. 32 builder.RegisterSource(new ViewRegistrationSource()); 33 34 // OPTIONAL: Enable property injection into action filters. 35 builder.RegisterFilterProvider(); 36 37 // Schedule 38 builder.Register(x => new StdSchedulerFactory().GetScheduler()).As<IScheduler>(); 39 40 // Schedule jobs 41 builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(x => typeof(IJob).IsAssignableFrom(x)); 42 43 // Set the dependency resolver to be Autofac. 44 _container = builder.Build(); 45 DependencyResolver.SetResolver(new AutofacDependencyResolver(_container)); 46 47 IScheduler sched = AutofacExt.GetFromFac<IScheduler>(); 48 sched.JobFactory = new AutofacJobFactory(_container); 49 50 51 IJobDetail job = JobBuilder.Create<TimeJob>() 52 .WithIdentity("job1", "group1") 53 .Build(); 54 55 ITrigger trigger = TriggerBuilder.Create() 56 .WithIdentity("1JobTrigger") 57 .WithSimpleSchedule(x => x 58 .RepeatForever() 59 .WithIntervalInSeconds(5) 60 ) 61 .StartNow() 62 .Build(); 63 64 sched.ScheduleJob(job, trigger); 65 sched.Start(); 66 } 67 68 /// <summary> 69 /// 从容器中获取对象 70 /// </summary> 71 /// <typeparam name="T"></typeparam> 72 public static T GetFromFac<T>() 73 { 74 return _container.Resolve<T>(); 75 } 76 }
1 public class AutofacJobFactory : IJobFactory 2 { 3 private readonly IContainer _container; 4 public AutofacJobFactory(IContainer container) 5 { 6 _container = container; 7 } 8 public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 9 { 10 return (IJob)_container.Resolve(bundle.JobDetail.JobType); 11 } 12 13 public void ReturnJob(IJob job) 14 { 15 16 } 17 }
[DisallowConcurrentExecution] public class TimeJob : IJob { private LogManagerApp logManager; public TimeJob() { logManager = AutofacExt.GetFromFac<LogManagerApp>(); } public void Execute(IJobExecutionContext context) { // } }
在Application_Start()里添加这段代码即可: AutofacExt.InitAutofac();