.NET Core中Quartz.NET的依賴注入


目錄

介紹

項目概況

創建配置文件

使用構造函數注入

使用選項模式

結論


介紹

Quartz.NET是一個方便的庫,允許您通過實現IJob接口來安排重復任務。然而,它的局限性在於,默認情況下,它僅支持無參數構造函數,這使得在其內部注入外部服務變得復雜,即,用於實現存儲庫模式。在本文中,我們將了解如何使用標准.NET Core DI容器解決此問題。

本文中提到的整個項目在以下Github存儲庫中提供。為了更好地遵循文章中的代碼,您可能需要查看它。

項目概況

我們來看看最初的解決方案結構。

項目QuartzDI.Demo.External.DemoService代表了一些我們無法控制的外部依賴。為了簡單起見,它的工作非常簡單。

項目QuartzDI.Demo是我們的工作項目,包含簡單的Quartz.NET作業。

 1 public class DemoJob : IJob
 2 {
 3     private const string Url = "https://i.ua";
 4  
 5     public static IDemoService DemoService { get; set; }
 6  
 7     public Task Execute(IJobExecutionContext context)
 8     {
 9         DemoService.DoTask(Url);
10         return Task.CompletedTask;
11     }
12 }

這是以直接的方式設置的:

 1 var props = new NameValueCollection
 2 {
 3     { "quartz.serializer.type", "binary" }
 4 };
 5 var factory = new StdSchedulerFactory(props);
 6 var sched = await factory.GetScheduler();
 7 await sched.Start();
 8 var job = JobBuilder.Create<DemoJob>()
 9     .WithIdentity("myJob", "group1")
10     .Build();
11 var trigger = TriggerBuilder.Create()
12     .WithIdentity("myTrigger", "group1")
13     .StartNow()
14     .WithSimpleSchedule(x => x
15         .WithIntervalInSeconds(5)
16         .RepeatForever())
17 .Build();
18 await sched.ScheduleJob(job, trigger);

我們通過作業的static屬性提供外部服務

1 DemoJob.DemoService = new DemoService();

由於該項目是一個控制台應用程序,在本文的課程中,我們必須手動安裝所有需要的基礎架構,並能夠更全面地了解.NET Core實際上為我們帶來了什么。

此時,我們的項目正在運行。最重要的是它很簡單,很棒。但是,如果我們想把它作為一個小工具,那么我們就會為這種簡單性付出代價。但這通常不是生產系統的情況。所以讓我們稍微調整一下以使其更靈活。

創建配置文件

其中一個缺點是我們硬編碼調用到DemoJob中的URL 。理想情況下,我們希望更改它,並根據我們的環境進行更改。.NET Core附帶了appsettings.json機制。

為了開始使用.NET Core配置機制,我們必須安裝幾個Nuget包:

1 Microsoft.Extensions.Configuration
2 Microsoft.Extensions.Configuration.FileExtensions
3 Microsoft.Extensions.Configuration.Json

讓我們創建一個具有這樣名稱的文件並在那里提取我們的URL:

1 {
2   "connection": {
3     "Url": "http://i.ua"
4   }
5 }

現在我們可以從配置文件中提取我們的值,如下所示:

1 var builder = new ConfigurationBuilder()
2                 .SetBasePath(Directory.GetCurrentDirectory())
3                 .AddJsonFile("appsettings.json", true, true);
4 var configuration = builder.Build();
5 var connectionSection = configuration.GetSection("connection");
6 DemoJob.Url = connectionSection["Url"];

請注意,要實現它,我們必須將Url從常量更改為屬性。

1 public static string Url { get; set; }

使用構造函數注入

通過static屬性注入服務對於一個簡單的項目來說很好,但是對於一個更大的項目,它可能帶來一些缺點:例如可能在沒有服務的情況下調用作業,因此失敗或在對象運行時期間改變依賴性,這使得更難以推理對象。要解決這些問題,我們應該使用構造函數注入。

雖然純依賴注入沒有任何問題,但是有些人認為你應該在本文中努力實現它,我們將使用Nuget包附帶的內置.NET Core DI容器Microsoft.Extensions.DependencyInjection。

現在我們指定我們依賴於構造函數參數的服務:

1 private readonly IDemoService _demoService;
2  
3 public DemoJob(IDemoService demoService)
4 {
5     _demoService = demoService;
6 }

 

為了調用作業的參數構造函數,Quartz.NET提供了IJobFactory接口。這是我們的實現:

 1 public class DemoJobFactory : IJobFactory
 2 {
 3     private readonly IServiceProvider _serviceProvider;
 4  
 5     public DemoJobFactory(IServiceProvider serviceProvider)
 6     {
 7         _serviceProvider = serviceProvider;
 8     }
 9  
10     public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
11     {
12         return _serviceProvider.GetService<DemoJob>();
13     }
14  
15     public void ReturnJob(IJob job)
16     {
17         var disposable = job as IDisposable;
18         disposable?.Dispose();
19     }
20 }

讓我們注冊我們的依賴項:

1 var serviceCollection = new ServiceCollection();
2 serviceCollection.AddScoped<DemoJob>();
3 serviceCollection.AddScoped<IDemoService, DemoService>();
4 var serviceProvider = serviceCollection.BuildServiceProvider();

拼圖的最后一塊是讓Quartz.NET使用我們的工廠。IScheduler有屬性JobFactory只是為了這件事。

1 sched.JobFactory = new DemoJobFactory(serviceProvider);

使用選項模式

現在我們可以使用配置選項來實現相同的技巧。同樣,我們的例子以Nuget包開始。這一次是Microsoft.Extensions.Options。

讓我們為配置選項創建一個強類型定義:

1 public class DemoJobOptions
2 {
3     public string Url { get; set; }
4 }

現在我們按如下方式填充它們:

serviceCollection.AddOptions();
serviceCollection.Configure<DemoJobOptions>(options =>
{
    options.Url = connectionSection["Url"];
});

並將它們注入構造函數中。不是我們直接注入IOptions<T>,不是options實例。

1 public DemoJob(IDemoService demoService, IOptions<DemoJobOptions> options)
2 {
3     _demoService = demoService;
4     _options = options.Value;
5 }

結論

在本文中,我們已經了解了如何利用.NET Core功能使Quartz.NET的使用更加靈活。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM