Asp.net-Mvc-3

如何創建需要使用 autofac 進行注入的 Quartz.NET 作業

  • January 24, 2021

我正在嘗試讓 Quartz.net (2.1.2) 與 IoC 容器 (autofac) 一起使用,因為我有需要在計劃作業中使用的服務。我在這個主題上找到了類似的文章,但我似乎無法找到一個帶有 autofac 特定註冊範例的文章。

以下文章涉及我遇到的相同問題:

如何使用 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 進行建構子注入 -使用 Quartz.NET 和 Simple Injector進行建構子注入

ASP.Net MVC 3、Ninject 和 Quartz.Net - 如何?

以下是相關程式碼:

全球.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;
   }

依賴註冊.cs

public class DependencyRegistration
{
   public void Register()
   {
       var builder = new ContainerBuilder();

       builder.RegisterControllers(Assembly.GetExecutingAssembly());
       builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());

       // Validation
       builder.RegisterType&lt;ValidatorFactory&gt;()
           .As&lt;IValidatorFactory&gt;()
           .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 =&gt; new StdSchedulerFactory().GetScheduler()).As&lt;IScheduler&gt;();

       // Schedule jobs
       builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(x =&gt; typeof(IJob).IsAssignableFrom(x));

       var container = builder.Build();
       DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

       //Schedule
       IScheduler sched = container.Resolve&lt;IScheduler&gt;();
       sched.JobFactory = new AutofacJobFactory(container);
       sched.Start();

       IJobDetail job = JobBuilder.Create&lt;ReleaseJob&gt;()
               .WithIdentity("1Job")
               .Build();

       ITrigger trigger = TriggerBuilder.Create()
           .WithIdentity("1JobTrigger")
           .WithSimpleSchedule(x =&gt; x
               .RepeatForever()
               .WithIntervalInSeconds(5)
           )
           .StartNow()
           .Build();

       sched.ScheduleJob(job, trigger);

       job = JobBuilder.Create&lt;HelloJob&gt;()
              .WithIdentity("2Job")
              .Build();

       trigger = TriggerBuilder.Create()
           .WithIdentity("2JobTrigger")
           .WithSimpleSchedule(x =&gt; x
               .RepeatForever()
               .WithIntervalInSeconds(5)
           )
           .StartNow()
           .Build();

       sched.ScheduleJob(job, trigger);
   }
}

作業工廠.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());
   }
}

發布服務模型.cs

public class ReleaseServiceModule : Module
{
   protected override void Load(ContainerBuilder builder)
   {
       builder.RegisterType&lt;ReleaseService&gt;()
           .As&lt;IReleaseService&gt;()
           .InstancePerLifetimeScope();
   }
}

我終於找到了問題所在。

我的發布服務使用的是在不同範圍內創建的數據儲存庫。

我通過創建一個新的測試服務發現了這一點,該服務只返回一個字元串,並且注入到石英作業中。

發現這一點後,我更改了發布服務呼叫的儲存庫的範圍,然後發布服務開始在石英作業中工作。

我向任何看到這個問題試圖幫助我的人道歉。因為沒有列出發布服務的程式碼,所以很難弄清楚哪裡出了問題。

我已經用我用於石英和 autofac 的最終工作綁定更新了程式碼。

引用自:https://stackoverflow.com/questions/16908342