我正在尝试使用Hangfire在我的MVC项目中运行后台作业。
我在控制器的构造函数中调用CompletionListener
方法:
Enqueue
public SHQSController(IUnitOfWork uow) : base(uow)
{
BackgroundJob.Enqueue(() => _Uow.CostRepository.Merge());
}
属性返回一个接口:
_Uow.CostRepository
但是,这项工作因篝火而失败,原因如下:
激活int时出错没有匹配的绑定是...
我发现如果我更改代码以便在public ICostRepository CostRepository
{
get
{
return new CostRepository(_Context, _CurrentOrganisationID);
}
}
的实现上调用作业而不是通过接口调用它,那么它可以工作:
即。在我的控制器中:
ICostRepository
在我的工作单元中:
BackgroundJob.Enqueue(() => _Uow.Test());
这里发生了什么?有没有办法排队一个允许我将我的实现放在我的存储库而不是我的工作单元的工作?
编辑:我在HangFire.State表中找到完整的错误消息完整错误是:
激活int时出错没有匹配的绑定和类型 是不可自我约束的。激活路径:2)注入依赖性 int到类型构造函数的参数currentOrganisationID CostRepository 1)CostRepository建议请求:1) 确保已为int定义了绑定。 2)如果绑定 在模块中定义,确保已加载模块 内核。 3)确保您没有意外创建超过 一个内核。 4)如果您正在使用构造函数参数,请确保 参数名称与构造函数参数名称匹配。 5)如果 您正在使用自动模块加载,确保搜索路径和 过滤器是正确的。
问题是public void Test()
{
new CostRepository(_Context, _CurrentOrganisationID).Merge();
}
所依赖的CurrentOrganisationID
。 CostRepository
当前是从CurrentOrganisationID
检索并在工作单元上设置的,它将其传递给存储库的构造函数,如上面的代码所示。
答案 0 :(得分: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
,现在可以正确解析依赖项。
顺便说一下,您可能会注意到我现在将organisationid
作为参数传递给该方法,之前它在存储库中可用。这是从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));
}