Как отправить dbcontext/единицу работы в фильтр заданий Hangfire

Мы используем 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)))

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
2 401
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По моему мнению, вы можете попробовать добавить 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 не работает, как я первоначально предполагал.

Получение ошибок компилятора. Класс атрибута LogToDB: public class LogToDB : Microsoft.AspNetCore.Mvc.TypeFilterAttribute, IClientFilter, IServerFilter, IElectStateFilter, IApplyStateFilter { Ошибка в этой строке конструктора: public LogToDB(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } ошибка: не указан аргумент, соответствующий требуемому формальному параметру «тип» «TypeFilterAttribute.TypeFilterAttribute(Type)». Спасибо за столь быстрый ответ.

ssvyper 26.04.2019 21:29

о, я думаю, что я сделал ошибку там. Должно быть new TypeFilterAttribute(typeof(LogToDB)). Также не уверен, используете ли вы класс GlobalConfiguration для настройки HangFire и GlobalJobFilters для добавления фильтров или используете метод расширения AddHangfire для IServicesCollection. Посмотрите мой отредактированный ответ и посмотрите, работает ли он.

Shahzad Hassan 26.04.2019 23:53

Спасибо, Шахзад; У меня есть образец для компиляции, но при попытке загрузить фильтр возникает ошибка времени выполнения. Я создал репозиторий с примером кода здесь: github.com/joelpereira/hfjobfilter/tree/master/HFJobFilter

ssvyper 27.04.2019 05:46

Хорошо, позвольте мне взглянуть. Я вернусь к вам по этому поводу. Я думаю, вам может понадобиться реализовать собственный JobActivator.

Shahzad Hassan 27.04.2019 11:28

@ssvyper Пожалуйста, взгляните на обновленный ответ. Я протестировал его, и он работает. надеюсь, это поможет

Shahzad Hassan 27.04.2019 23:33

Другие вопросы по теме