Reputation: 1077
Im trying to use Hangfire with Microsoft.Extensions.DependencyInjection in an Asp.Net 4.7.2 MVC Application. I have the DI setup and working, I just cant seem to configure Hangfire correctly. The current implementation below runs the dashboard, but executing a background task returns the error: JobActivator returned NULL instance of the 'Dh.Web.Services.EmailService' type.
I know EmailService is correctly setup in DI because I can access it using DI in the same controller that is calling the BackgroundJob.Enqueue method.
My Implementation is:
HangfireActivator.cs
public class HangfireActivator : JobActivator
{
private readonly IServiceProvider _serviceProvider;
public HangfireActivator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public override object ActivateJob(Type type)
{
return _serviceProvider.GetService(type);
}
}
ConfigureHangfire Method inside startup.cs
private void ConfigureHangfire(IServiceProvider serviceProvider, IAppBuilder app)
{
var hangfireConnString = ConfigurationManager.ConnectionStrings["Dh"].ConnectionString;
GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseActivator(new HangfireActivator(serviceProvider))
.UseSqlServerStorage(hangfireConnString, new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.FromSeconds(10),
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true,
}
);
app.UseHangfireServer(new BackgroundJobServerOptions {WorkerCount = 3});
var options = new DashboardOptions()
{
Authorization = new[] {new SystemAuthorizationFilter()}
};
app.UseHangfireDashboard("/hangfire",options);
}
and then finally Configuration Method in Startup.cs
public void Configuration(IAppBuilder app)
{
var services = new ServiceCollection();
//App DI
ConfigureServices(services);
var serviceProvider = services.BuildServiceProvider();
var resolver = new DefaultDependencyResolver(serviceProvider);
DependencyResolver.SetResolver(resolver);
//Hangfire
ConfigureHangfire(serviceProvider,app);
}
I have a suspicion that its the line: var serviceProvider = services.BuildServiceProvider();
that is creating a seperate service provider to the one i setup all my App DI in, but i dont know how to get the ServiceProvider to the UseActivator option in Hangfire without that line...
I would really really appreciate any input. Thank you!
Upvotes: 4
Views: 1647
Reputation: 1077
I had registered in my DI:
services.AddTransient<IEmailService,EmailService>();
However adding this to register the concrete class without the interface worked.
services.AddTransient<EmailService>();
Upvotes: 1