我为调度作业创建了以下抽象:
public abstract class BaseJob
{
public string? JobId { get; set; }
}
public interface IJobData
{ }
public interface IJob<in TJobData> where TJobData : IJobData
{
Task ExecuteAsync(TJobData jobData);
}
我利用工厂创造就业机会:
public class JobCreator<TJob, TJobData>
where TJob : IJob<TJobData>, new()
where TJobData : IJobData
{
public async Task ExecuteAsync(TJobData jobData)
{
var job = new TJob();
await job.ExecuteAsync(jobData);
}
}
示例实现:
public record ForgotPasswordJobData() : IJobData;
public class ForgotPasswordJob: BaseJob, IJob<ForgotPasswordJobData>
{
private readonly IMailService _mailer;
public ForgotPasswordJob(IMailer mailer)
{
_mailer = mailer;
}
public Task ExecuteAsync(ForgotPasswordJobData jobData)
{
// Do something
// Send mail
}
}
这是作业排队的方式:
JobClient.Enqueue<JobCreator<ForgotPasswordJob, ForgotPasswordJobData>>(job => job.ExecuteAsync(jobData));
因为ForgetPasswordJobs没有无参数构造函数,所以我得到一个CS0310错误,它说
为了将其用作泛型类型或方法JobCreator中的参数参数,类型“忘记密码作业”必须是具有公共无参数构造函数的非抽象类型
如何在IJob的实现中使用依赖关系?
您需要告诉您的JobCreater
如何实例化TJob
:
public class JobCreator<TJob, TJobData>
where TJob : IJob<TJobData>
where TJobData : IJobData
{
public async Task ExecuteAsync(Func<TJob> createJob, TJobData jobData)
{
var job = createJob();
await job.ExecuteAsync(jobData);
}
}
var mailService = new MailService();
JobClient.Enqueue<JobCreator<ForgotPasswordJob, ForgotPasswordJobData>>(
job => job.ExecuteAsync(() => new ForgotPasswordJob(mailService), jobData));
虽然我不确定JobCreator
是否真的有必要
您可以更改您的JobClient
,以接受已经实例化的作业,考虑到它不依赖于Enline中的任何内容:
void Enqueue<TJob, TJobData>(TJob job, TJobData jobData)
where TJob : IJob<TJobData>
where TJobData : IJobData
{
// ...
Task jobTask = job.ExecuteAsync(jobData);
// ...
}
var forgotPasswordJob = new ForgotPasswordJob(new MailService());
JobClient.Enqueue(forgotPasswordJob, jobData);