在 ASP Net Core 中使用 hangfire 激活 类
Activating classes with hangfire in ASP Net Core
我在配置 HangFire 时遇到问题。我正试图触发并忘记 ASP Net Core 中的一个警报呼叫。
报警服务:
public void FireAndForgetAlarm(int statusCode, string message, string subject = null, IList<string> attachmentFilePaths = null)
{
BackgroundJob.Enqueue(() => Alarm(statusCode, message, subject,
attachmentFilePaths));
}
*报警方式为public.
错误描述:
warn: Hangfire.AutomaticRetryAttribute[0]
Failed to process the job 'eb7f76ea-7522-49e2-b7b9-3ed3ed091a0c': an exception occurred. Retry attempt 2 of 10 will be performed in 00:01:02.
System.InvalidOperationException: Unable to resolve service for type 'Wms.Alarming.AlarmingConfig' while attempting to activate 'Wms.Alarming.AlarmingService'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
at Hangfire.AspNetCore.AspNetCoreJobActivatorScope.Resolve(Type type)
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass9_0.b__0()
at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func1 continuation) at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass9_1.<PerformJobWithFilters>b__2() at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable
1 filters)
at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)
我的启动 class 包含:
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureAlarmingServices(new AlarmingConfig()
{
Port = int.Parse(ConfigurationManager.AppSettings["mailPort"]), // for SSL 465
Sender = ConfigurationManager.AppSettings["mailSender"],
SmtpServer = ConfigurationManager.AppSettings["smtpServer"],
Recipients = ConfigurationManager.AppSettings["mailRecipients"],
SenderPassword = ConfigurationManager.AppSettings["mailPassword"]
});
services.AddHangfire(c => {
c.UseMemoryStorage();
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHangfireServer(new BackgroundJobServerOptions(){Activator = new AspNetCoreJobActivator(app.ApplicationServices.GetRequiredService<IServiceScopeFactory>())});
}
备注:
- 我已经为启动尝试了多个版本class,包括将激活器放在 AddHangire 方法中。没有任何尝试真正奏效,我也正确地遵循了文档。
- 警报服务已正确配置,无需 HangFire 即可正常工作。
- 在警报配置中传递文字不起作用
- 唯一的解决方案是使方法静态化,但这不允许很好的 DI
- 我在他们的文档中看到了一个解决方案,他们总是有一个默认构造函数并使用参数调用构造函数。但是,这对我来说是不可能的,因为我也在注入记录器。
评论中要求的扩展方法内容:
public static void ConfigureAlarmingServices(this IServiceCollection collection, AlarmingConfig config)
{
collection.AddSingleton<IAlarmingService>(x=> new
AlarmingService(x.GetService<ILogger<IAlarmingService>>(), config));
}
首先,您看到的异常的重要部分是:
Unable to resolve service for type 'Wms.Alarming.AlarmingConfig' while attempting to activate 'Wms.Alarming.AlarmingService'
这表明您在代码中的某处(您尚未显示的部分)正在尝试注入 AlarmingService
.
的实例
您已经配置了如何解析接口 IAlarmingService
的单例服务,这意味着您应该能够 class 依赖于 IAlarmingService
。但是,如果您的 class 具体依赖于 AlarmingService
(而不是接口),您将收到此错误,因为您尚未定义如何解析 AlarmingService
.[=20 类型的依赖项=]
要么...
- 您没有显示的代码应该只依赖于
IAlarmingService
而不是具体的 class 本身 (AlarmingService
) 或..
- 您还需要配置 DI 容器来处理特定类型
AlarmingService
的依赖项,例如:
public static void ConfigureAlarmingServices(this IServiceCollection collection, AlarmingConfig config)
{
collection.AddSingleton<AlarmingService>(
x => new AlarmingService(x.GetService<ILogger<AlarmingService>>(), config));
collection.AddSingleton<IAlarmingService>(x => x.GetService<AlarmingService>());
}
我认为第一点是你需要修复的。
我在配置 HangFire 时遇到问题。我正试图触发并忘记 ASP Net Core 中的一个警报呼叫。
报警服务:
public void FireAndForgetAlarm(int statusCode, string message, string subject = null, IList<string> attachmentFilePaths = null)
{
BackgroundJob.Enqueue(() => Alarm(statusCode, message, subject,
attachmentFilePaths));
}
*报警方式为public.
错误描述:
warn: Hangfire.AutomaticRetryAttribute[0] Failed to process the job 'eb7f76ea-7522-49e2-b7b9-3ed3ed091a0c': an exception occurred. Retry attempt 2 of 10 will be performed in 00:01:02. System.InvalidOperationException: Unable to resolve service for type 'Wms.Alarming.AlarmingConfig' while attempting to activate 'Wms.Alarming.AlarmingService'. at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type) at Hangfire.AspNetCore.AspNetCoreJobActivatorScope.Resolve(Type type) at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context) at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass9_0.b__0() at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func
1 continuation) at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass9_1.<PerformJobWithFilters>b__2() at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable
1 filters) at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context) at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)
我的启动 class 包含:
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureAlarmingServices(new AlarmingConfig()
{
Port = int.Parse(ConfigurationManager.AppSettings["mailPort"]), // for SSL 465
Sender = ConfigurationManager.AppSettings["mailSender"],
SmtpServer = ConfigurationManager.AppSettings["smtpServer"],
Recipients = ConfigurationManager.AppSettings["mailRecipients"],
SenderPassword = ConfigurationManager.AppSettings["mailPassword"]
});
services.AddHangfire(c => {
c.UseMemoryStorage();
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHangfireServer(new BackgroundJobServerOptions(){Activator = new AspNetCoreJobActivator(app.ApplicationServices.GetRequiredService<IServiceScopeFactory>())});
}
备注:
- 我已经为启动尝试了多个版本class,包括将激活器放在 AddHangire 方法中。没有任何尝试真正奏效,我也正确地遵循了文档。
- 警报服务已正确配置,无需 HangFire 即可正常工作。
- 在警报配置中传递文字不起作用
- 唯一的解决方案是使方法静态化,但这不允许很好的 DI
- 我在他们的文档中看到了一个解决方案,他们总是有一个默认构造函数并使用参数调用构造函数。但是,这对我来说是不可能的,因为我也在注入记录器。
评论中要求的扩展方法内容:
public static void ConfigureAlarmingServices(this IServiceCollection collection, AlarmingConfig config)
{
collection.AddSingleton<IAlarmingService>(x=> new
AlarmingService(x.GetService<ILogger<IAlarmingService>>(), config));
}
首先,您看到的异常的重要部分是:
Unable to resolve service for type 'Wms.Alarming.AlarmingConfig' while attempting to activate 'Wms.Alarming.AlarmingService'
这表明您在代码中的某处(您尚未显示的部分)正在尝试注入 AlarmingService
.
您已经配置了如何解析接口 IAlarmingService
的单例服务,这意味着您应该能够 class 依赖于 IAlarmingService
。但是,如果您的 class 具体依赖于 AlarmingService
(而不是接口),您将收到此错误,因为您尚未定义如何解析 AlarmingService
.[=20 类型的依赖项=]
要么...
- 您没有显示的代码应该只依赖于
IAlarmingService
而不是具体的 class 本身 (AlarmingService
) 或.. - 您还需要配置 DI 容器来处理特定类型
AlarmingService
的依赖项,例如:
public static void ConfigureAlarmingServices(this IServiceCollection collection, AlarmingConfig config)
{
collection.AddSingleton<AlarmingService>(
x => new AlarmingService(x.GetService<ILogger<AlarmingService>>(), config));
collection.AddSingleton<IAlarmingService>(x => x.GetService<AlarmingService>());
}
我认为第一点是你需要修复的。