I have an existing C# ASP.NET application with a user interface and various buttons to initiate actions. The actions make synchronous method calls on a class which is a singleton and I’ll call this class ServiceLayer. This layer also initializes a data model.
I want to schedule some of the actions from the UI to occur at certain times of day. I believe Quartz.NET provides all the necessary features I need to do this. I can successfully call methods on the singleton class ServiceLayer from the Execute(IJobExecutionContext context) of each Job class (i.e. classes which implement the IJob interface). However, I don’t like using this approach for a few reasons:
- Difficult to unit-test (e.g. I have to ensure the singleton is initialized before I can do anything)
- Scaling up if many jobs are called
- Thread safety issues associated with calling multiple methods on the singleton class at the same time.
My question is what is the best design pattern to handle this case instead of calling methods on a singleton directly? I believe I need to make use of the JobDataMap somehow but I’m not sure how. Should I be looking at a producer-consumer or a queuing approach?
You might want to consider implementing a custom job factory that injects your service layer object into the job. There are already implementations of custom factories for the most popular DI containers out there, so you could go with one of those or build your own. This would allow you to pass a reference to your service layer object each time you create a job and should help with unit testing. It would also resolve the singleton issue.
As far as scaling up is concerned, you could use the JobDataMap to pass in things like connection strings or server names, allowing you to load balance or distribute work across your servers.
Here are some posts describing the custom job factory approach if you end up going down that path.