提问者:小点点

遇到CS0310错误时如何在构造函数中使用参数


我为调度作业创建了以下抽象:

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的实现中使用依赖关系?


共1个答案

匿名用户

您需要告诉您的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);