問題:
使用 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();
