I have issues with configuring HangFire. I'm trying to fire and forget an alarming call in ASP Net Core.
Alarming Service:
public void FireAndForgetAlarm(int statusCode, string message, string subject = null, IList<string> attachmentFilePaths = null)
{
BackgroundJob.Enqueue(() => Alarm(statusCode, message, subject,
attachmentFilePaths));
}
*The Alarm method is public.
Error description:
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)
My startup class contains:
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>())});
}
Notes:
Content of extension method as requested in comments:
public static void ConfigureAlarmingServices(this IServiceCollection collection, AlarmingConfig config)
{
collection.AddSingleton<IAlarmingService>(x=> new
AlarmingService(x.GetService<ILogger<IAlarmingService>>(), config));
}
First off, the important part of the exception you are seeing is:
Unable to resolve service for type 'Wms.Alarming.AlarmingConfig' while attempting to activate 'Wms.Alarming.AlarmingService'
Which indicates that somewhere in your code (a part you haven't shown yet) you are trying to inject an instance of AlarmingService
.
You've configured how to resolve a singleton service for the interface IAlarmingService
, which means you should be able to have a class depend on IAlarmingService
. However, if your class depends specfically on AlarmingService
(not the interface), you will get this error, because you have not defined how to resolve a dependency of type AlarmingService
.
Either...
IAlarmingService
and not the concrete class itself (AlarmingService
) or..AlarmingService
, e.g.: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>());
}
I think the first point is what you need to fix.