【问题标题】:How to use parameters in constructor when facing CS0310 error遇到 CS0310 错误时如何在构造函数中使用参数
【发布时间】:2021-12-08 14:56:42
【问题描述】:

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

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));

因为 ForgetPasswordJob 没有无参数构造函数,所以我得到一个 CS0310 错误,这就是说

“ForgotPasswordJob”类型必须是非抽象类型,具有公共 无参数构造函数,以便将其用作参数“参数” 在泛型类型或方法 'JobCreator'

如何在 IJob 的实现中使用依赖项?

【问题讨论】:

  • 你好像漏掉了一些标签

标签: c#


【解决方案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 以接受已经实例化的作业,考虑到它不依赖 Enqueue 中的任何内容:

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);

【讨论】:

  • +1 谢谢!有没有办法做到这一点,而不使用 () => new ForgotPasswordJob(mailService)?底层作业服务无法序列化此表达式“作业方法参数中不支持匿名函数、委托和 lambda 表达式”。但是,只需使用 job => job.ExecuteAsync(jobData) 即可。
  • @Upvote 查看我的更新;也许您可以完全删除您的JobCreator
  • 喜欢这个主意。效果很好!
猜你喜欢
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
相关资源
最近更新 更多