DI Service Usage in Quartz.NET registration
I am using Quartz.NET as my scheduling framework, because Quartz.NET has a built-in support for persistent storage, which solves many problems for me out of the box. The problem is the configuration of the connection string for the database. I got a scoped service which resolves the database connection string, since the appsettings.json only includes the template connection string. The actual user and password comes from a vault during startup. Therefore I have to use the service. As far as I know, Quartz.NET has no overload to utilize the IServiceProvider. Because of that I created this overload method
Which allows me to do this
My question is if there is a better alternative? Somehow I am unhappy with the solution. I dont know why but it feels wrong.
18 Replies
when i last used quartz, there was no way to have it sync job execution with multiple app instances, which made it a big no no for any serious app, as scalability is essentially not given. just want to make sure this is not a concern for you, or they have added support for it?!
we use hangfire, as the whole job scheduling is done in a database and you can set up jobs to not run in parallel.
i am not certain, but i believe hangfire can be used in a way that allows for services to be injected as usual.
i just remember that there was barely any migration effort between the two, so i assum u can use di there as well
let me check the code
At least I've tested it several times in the cloud by now and it supports clustering out of the box aswell. Another reason why we are using it at the moment. Nonetheless we didn't have multiple replicas in production yet. We only tested it with multiple replicas so I can't give any warranty. See more here https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/advanced-enterprise-features.html
We also considered using Hangfire but hangfire has a license model when I remember correctly?
Lesson 11: Advanced (Enterprise) Features | Quartz.NET
Open-source scheduling framework for .NET.
Yes Hangfire is not free. Therefore no option for me at the moment. Sadly
https://www.hangfire.io/pricing/
Hangfire – Background Jobs for .NET and .NET Core
An easy way to perform fire-and-forget, delayed and recurring tasks in ASP.NET applications. No Windows Service required, backed by persistent storage.
not sure what you are talking about ... basically first sentence is:
Hangfire is completely free even for commercial use.
but ok. this is not about hangfire.
yes its possible to use DI in hangfire!

but now how to do in quartz. i need to go far back in history ... 😄
Oh bruh you are right. I only saw the prices and were like "nope"
But why are there paid plans lol I am not very educated about hangfire - Do they offer a own service?
quarz can do DI as well
you have to do it the other way arround though.
let the di create the jobs for you, and then start them
Ah now I do understand - I know that Quartz supports DI in the jobs - I am already using it there. But does Quartz also supports DI during it's configuration in the startup process
oh
well i mean using the service provider to build everything beforehand is odd.
Yes, but I don't see any other solution yet, since I must use the ISecretConnectionStringProvider service to receive the connectionString
For example EntityFramework has a similar feature where you can access the ServiceProvider during
.AddDbContext<T>
i'd probably extract that db connection string building into a piece of config codeand use this in your db and in your quartz configuration
I mean I got all parts of the connection string in the appsettings, since the vault secrets get appended to the appsettings during startup. But I cant access IConfiguration either since we already know there is no builtin serviceProvider support
so you are not really about quarz, but rather about the henn-and-egg problem of creating a database then using that database to extract a connection string in order to use this in another database connection
pass in iconfiguration during startup
you are doing that already?!
Yes and no. I don't have a "first" database there I get the actual connectionString from. The username and password for the quartz connectionString comes from a vault (hashicorp to be exact). But yes the general problem is receiving the connectionString during the quartz configuration.
It might be possible to do quartz, but the user and passwords are rotated in the vault. Therefore my service will often use different credentials. Using IConfiguration the credentials would be fixed and couldn't be rotated other than with a service restart. The custom service providing the connection string allows me to always resolve the newest credentials without having to restart the service
The appsettings looks like this
But the postgres section is being appended during startup from the vault and it can be rotated. So they are not always the same.
Quartz has supported clustering for like a decade.
I'm not 100% otherwise sure what you're asking about configuration.
Quartz configuration is stored in the Options pattern now, isn't it?
Eh, sorta. Kinda. Everything the DI does is just to wire up SchedulerBuilder. But it does process QuartzOptions
So you can just Configure QuartzOptions to set whatever properties you want.
Yup. AddQuartz uses SchedulerBuilder to provide the nice extension methods. But all those are doing is compiling the traditional quartz configuration properties collection. And then those get dumped into QuartzOptions. And later the scheduler uses IOptions<QuartzOptions>
So you can just set your own connectiojn string in a IConfigure or IPostConfigure.
Why haven't I ever thought about that - The IConfigure<QuartzOptions> is a very good Idea - Thanks a lot, that will solve My Problem!
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View