I am using HangFire
and EntityFramework
for recurring job
public void Start(IContainer container)
{
GlobalConfiguration.Configuration
.UseColouredConsoleLogProvider(LogLevel.Debug)
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseActivator(new MyActivator(container))
.UseRecommendedSerializerSettings();
RecurringJob.AddOrUpdate<EveryMinute>((x) => x.ExecuteAsync(), Cron.Minutely);
}
Activator:
public class MyActivator : JobActivator
{
private readonly IContainer _container;
public MyActivator (IContainer container)
{
_container = container;
}
public override object ActivateJob(Type type)
{
return _container.Resolve(type);
}
}
Then I had ctor
initialization of Datacontext
and RepositoryA
public EveryMinute(DataContext dataContext,RepositoryA repositoryA)
{
_dataContext = dataContext;
_repositoryA = repositoryA;
}
However when i retrieved data from DB in each minute like bellow i received wrong data(Item was updated outside of Hangfire job by other application).
public async Task ExecuteAsync()
{
var dbItem = _dataContext.Items.Single(x => x.Id == 1);
//dbItem.StateProperty property is old
}
It looks like item or DataContext is 'cached' from time of job creation(application start). Because when I used
public EveryMinute()
{
_dataContext = new DataContext();
_repositoryA = new RepositoryA(_dataContext);
}
It works fine.
Am I using activator wrong? Or how to specify that I need new instance DataContext
for each call of dependency injection?
Jobs in Hangfire shares instance of activator.
Therefore I used Hangfire Autofac nuget -
Hangfire.Autofac
.you can have specify for dependency to have instance per job
and then in config