I have ASP.NET Web API application. The application is using Unity as IoC container. The application is also using Hangfire and I am trying to configure Hangfire to use Unity.
So based on documentation i am using Hangfire.Unity which registers the unity container as a current job activator in Hangfire.
I have a class which has dependency on IBackgroundJobClient
public class MyService
{
private MyDBContext _dbContext = null;
private IBackgroundJobClient _backgroundJobClient = null;
public MyService(MyDbContext dbContext, IBackgroundJobClient backgroundJobClient)
{
_dbContext = dbContext;
_backgroundJobClient = backgroundJobClient;
}
}
However even after configuring Hangfire.Unity
it could not create & pass instance of BackgroundJobClient
So i had to register every dependency of BackgroundJobClient
with unity container.
Unity Registration
public class UnityConfig
{
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<MyDbContext>(new HierarchicalLifetimeManager(), new InjectionFactory(x => new MyDbContext()));
// register hangfire dependencies
container.RegisterType<IBackgroundJobClient, BackgroundJobClient>();
container.RegisterType<JobStorage, SqlServerStorage>(new InjectionConstructor("HangfireConnectionString"));
container.RegisterType<IJobFilterProvider, JobFilterAttributeFilterProvider>(new InjectionConstructor(true));
container.RegisterType<IBackgroundJobFactory, BackgroundJobFactory>();
container.RegisterType<IRecurringJobManager, RecurringJobManager>();
container.RegisterType<IBackgroundJobStateChanger, BackgroundJobStateChanger>();
}
}
OWIN Startup
public class Startup
{
public void Configuration(IAppBuilder app)
{
var container = UnityConfig.GetConfiguredContainer();
Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("HangfireConnectionString");
Hangfire.GlobalConfiguration.Configuration.UseUnityActivator(container);
// if i dont call UseSqlServerStorage() above then UseHangfireDashboard() method fails with exception
//JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.
app.UseHangfireDashboard();
app.UseHangfireServer();
RecurringJob.AddOrUpdate<MyService>(x => x.Prepare(), Cron.MinuteInterval(10));
}
}
Code is working with such configuration. However i have questions:
Is this the correct way of configuring Unity with Hangfire?
Why do i need to invoke Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("HangfireConnectionString")
in OWIN startup even though SqlServerStorage
is already registered with Unity container as JobStorage
?
If i dont invoke UseSqlServerStorage() method in OWIN startup then i get exception on app.UseHangfireDashboard()
method.
JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.