2

我正在尝试使用 Hangfire 在我的 MVC 项目中运行后台作业。

Enqueue我在控制器的构造函数中调用该方法:

public SHQSController(IUnitOfWork uow) : base(uow)
{
    BackgroundJob.Enqueue(() => _Uow.CostRepository.Merge());
}

_Uow.CostRepository属性返回一个接口:

public ICostRepository CostRepository
{
    get
    {
       return new CostRepository(_Context, _CurrentOrganisationID);
    }
}

但是由于以下原因,该作业在hangfire中失败:

错误激活 int 没有匹配的绑定是 av...</p>

我发现如果我更改代码以便在实现ICostRepository而不是通过接口调用作业,它可以工作:

即在我的控制器中:

BackgroundJob.Enqueue(() => _Uow.Test());

在我的工作单元中:

public void Test()
{
    new CostRepository(_Context, _CurrentOrganisationID).Merge();
}

这里发生了什么?有没有办法让我将我的实现放在我的存储库而不是我的工作单元中?

编辑:我在 HangFire.State 表中找到了完整的错误消息完整的错误是:

激活 int 时出错 没有匹配的绑定可用,并且类型不是自绑定的。激活路径: 2) 将依赖 int 注入到 CostRepository 类型的构造函数的参数 currentOrganisationID 1) 请求 CostRepository 建议: 1) 确保您已为 int 定义绑定。2) 如果绑定是在模块中定义的,请确保该模块已加载到内核中。3) 确保您没有意外创建多个内核。4) 如果您使用构造函数参数,请确保参数名称与构造函数参数名称匹配。5) 如果您使用自动模块加载,请确保搜索路径和过滤器正确。

所以问题是CurrentOrganisationID依赖CostRepository的。当前CurrentOrganisationID是从工作单元上的和设置中检索的HttpContext,它会将其传递给存储库的构造函数,如我上面的代码所示。

4

1 回答 1

0

我认为这条线的问题是:

BackgroundJob.Enqueue(() => _Uow.CostRepository.Merge());

是Hangfire将此解释为实例化实现ICostRepository并运行其Merge方法的要求,而不是实例化实现IUow并在其上运行CostRepository.Merge()

我通过在控制器上创建一个公共方法来解决这个问题:

public void Merge(int organisationid)
{
    _Uow.CostRepository.MergeSHQSCostsTable(organisationid);
}

并将其传递给Enqueue方法:

BackgroundJob.Enqueue(() => Merge(organisationid));

Hangfire 排队的作业现在是SHQSController.Merge,并且依赖关系现在已正确解决。

顺便说一句,您可能会注意到我现在将organisationidin 作为参数传递给该方法,而以前它在存储库中可用。这是从 中检索的,HttpContext并且由于在从后台作业实例化控制器时这不可用,因此我必须创建另一个从构造函数调用的私有方法,以便将其organisationid连接到后台作业:

所以,而不是:

public SHQSController(IUnitOfWork uow) : base(uow)
{
    BackgroundJob.Enqueue(() => _Uow.CostRepository.Merge(CurrentOrganisationId));
}

我有:

public SHQSController(IUnitOfWork uow) : base(uow)
{
   EnqueueMerge(CurrentOrganisationID);
}

private void EnqueueMerge(int organisationid)
{
    BackgroundJob.Enqueue(() => Merge(organisationid));
}
于 2018-04-25T09:58:41.137 回答