如何将dbcontext /工作单元发送到Hangfire作业过滤器

时间:2019-04-26 14:34:43

标签: c# asp.net-core hangfire

我们正在将Hangfire用于一些夜间和长期运行的作业,并且我们正在单独数据库中跟踪每个作业的其他相关详细信息/元数据,以避免将来出现Hangfire升级问题。 作业过滤器(https://docs.hangfire.io/en/latest/extensibility/using-job-filters.html)可以帮助我们以更简单的方式跟踪每个作业的状态,但是我找不到如何将依赖关系发送到作业过滤器的示例。

我们正在运行具有依赖项注入(DI)和存储库+工作单元的ASP.NET Core。

我如何能够从作业过滤器中访问数据库上下文(或工作单元或可通过DI获得的任何其他项目)?

谢谢

编辑 我已经创建了一个带有一个小样本项目的存储库,该项目概述了我要在此处进行的操作: https://github.com/joelpereira/hfjobfilter/tree/master/HFJobFilter

它可以编译,但是在行上有一个错误:     .UseFilter(new TypeFilterAttribute(typeof(LogToDbAttribute)))

1 个答案:

答案 0 :(得分:1)

从我的头开始,您可以尝试将JobFilter添加为TypeFilter,它将自动注入依赖项(如果在LogEverythingAttribute的构造函数中有此依赖项),因此可以从您提供的链接:

public class EmailService
{
    [TypeFilter(typeof(LogEverything))]
    public static void Send() { }
}

GlobalJobFilters.Filters.Add(new TypeFilterAttribute(typeof(LogEverythingAttribute())));

免责声明:我自己还没有测试过上述内容,因此请告诉我是否可行。

已编辑

尝试像下面ConfigureServices中那样配置Hangfire,看看是否可行

services.AddHangfire(config =>
{
    config.UseFilter(new TypeFilterAttribute(typeof(LogToDbAttribute)));

    // if you are using the sqlserverstorage, uncomment the line and provie
    // the required prameters
    // config.UseSqlServerStorage(connectionString, sqlServerStorageOptions);
});

更新后的答案

请查看我对您提供的代码所做的changes。我已经对其进行了测试,并且可以正常工作。以下是几点注意事项。

请查看我如何使用利用HttpClientFactory和类型客户端的AddHttpClient方法注册HttpClient。这是使用HttpClient的推荐方法。您可以详细了解here

services.AddHttpClient<HfHttpClient>(client =>
{
    client.BaseAddress = new Uri("http://localhost:44303");

    // you can set other options for HttpClient as well, such as
    //client.DefaultRequestHeaders;
    //client.Timeout
    //...
});

此外,您需要注册LogDbAttribute,然后使用IServiceProvider

在UseFilter调用中解析它。
// register the LogToDbAttribute
services.AddSingleton<LogToDbAttribute>();
// build the service provider to inject the dependencies in LogDbAttribute
var serviceProvider = services.BuildServiceProvider();
services.AddHangfire(config => config
.UseSqlServerStorage(Configuration.GetConnectionString("HangfireDBConnection"))
.UseFilter(serviceProvider.GetRequiredService<LogToDbAttribute>()));

我还注入了ILogger以证明它正在工作。由于某种原因,如果您尝试对HttpClient进行任何操作,它将挂起。也许是因为这是一个后台作业,并且所有HttpClient调用都是异步的,因此它不会返回,并且两个进程试图互相等待。

如果您打算注入HttpClient,则可能需要调查一下。但是,记录器工作正常。

此外,您不需要从TypeFilterAttribute继承LogDbAttribute。 TypeFilterAttribute解决方案不像我最初建议的那样起作用。