Мы используем Hangfire для некоторых ночных и длительных заданий и отслеживаем дополнительные связанные детали/метаданные для каждого задания в отдельной базе данных, чтобы избежать проблем с обновлением Hangfire в будущем. Фильтр заданий (https://docs.hangfire.io/en/latest/extensibility/using-job-filters.html) поможет нам гораздо проще отслеживать состояние каждого задания, но я не могу найти пример того, как отправлять зависимости в фильтр заданий.
Мы используем ASP.NET Core с внедрением зависимостей (DI) и шаблонами репозиторий + единица работы.
Как я могу получить доступ к контексту базы данных (или единице работы или любым другим элементам, доступным через DI) из фильтра заданий?
Спасибо
РЕДАКТИРОВАТЬ Я создал репозиторий с небольшим примером проекта, в котором показано, что я пытаюсь здесь сделать: https://github.com/joelpereira/hfjobfilter/tree/master/HFJobFilter
Он компилируется, но в строке есть ошибка: .UseFilter (новый TypeFilterAttribute (typeof (LogToDbAttribute)))





По моему мнению, вы можете попробовать добавить JobFilter как ТипФильтр, и он автоматически внедрит зависимости, если таковые имеются, в конструкторе вашего LogEverythingAttribute, поэтому изменив пример из предоставленной вами ссылки:
public class EmailService
{
[TypeFilter(typeof(LogEverything))]
public static void Send() { }
}
GlobalJobFilters.Filters.Add(new TypeFilterAttribute(typeof(LogEverythingAttribute())));
Отказ от ответственности: Я сам не проверял описанное выше, поэтому, пожалуйста, дайте мне знать, если это сработает.
Отредактировано
Попробуйте настроить Hangfire, как показано ниже в ConfigureServices, и посмотрите, работает ли это.
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);
});
ОБНОВЛЕННЫЙ ОТВЕТ
Пожалуйста, взгляните на изменения, который я сделал для предоставленного вами кода. Я протестировал его, и он работает. Несколько моментов, на которые следует обратить внимание ниже.
Посмотрите, как я зарегистрировал HttpClient, используя метод AddHttpClient, который использует HttpClientFactory и Typed Clients. Это рекомендуемый способ использования HttpClient. Подробнее об этом можно прочитать здесь
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, а затем разрешить его в вызове UseFilter, используя IServiceProvider
// 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, возможно, вам придется изучить его. Тем не менее, регистратор работает нормально.
Кроме того, вам не нужно наследовать LogDbAttribute от TypeFilterAttribute. Решение TypeFilterAttribute не работает, как я первоначально предполагал.
о, я думаю, что я сделал ошибку там. Должно быть new TypeFilterAttribute(typeof(LogToDB)). Также не уверен, используете ли вы класс GlobalConfiguration для настройки HangFire и GlobalJobFilters для добавления фильтров или используете метод расширения AddHangfire для IServicesCollection. Посмотрите мой отредактированный ответ и посмотрите, работает ли он.
Спасибо, Шахзад; У меня есть образец для компиляции, но при попытке загрузить фильтр возникает ошибка времени выполнения. Я создал репозиторий с примером кода здесь: github.com/joelpereira/hfjobfilter/tree/master/HFJobFilter
Хорошо, позвольте мне взглянуть. Я вернусь к вам по этому поводу. Я думаю, вам может понадобиться реализовать собственный JobActivator.
@ssvyper Пожалуйста, взгляните на обновленный ответ. Я протестировал его, и он работает. надеюсь, это поможет
Получение ошибок компилятора. Класс атрибута LogToDB:
public class LogToDB : Microsoft.AspNetCore.Mvc.TypeFilterAttribute, IClientFilter, IServerFilter, IElectStateFilter, IApplyStateFilter {Ошибка в этой строке конструктора:public LogToDB(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; }ошибка: не указан аргумент, соответствующий требуемому формальному параметру «тип» «TypeFilterAttribute.TypeFilterAttribute(Type)». Спасибо за столь быстрый ответ.