JobActivator not working in .Net Core 2.x

Hello,

I have setting up a simple job activator like that :

public class HangfireJobActivator : Hangfire.JobActivator
{
    private readonly IServiceProvider _serviceProvider;

    public HangfireJobActivator(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public override object ActivateJob(Type type)
    {
        return _serviceProvider.GetService(type);
    }
}

And set it in my Startup.cs like that :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
 {
         GlobalConfiguration.Configuration.UseActivator(new HangfireServiceActivator(serviceProvider));
         app.UseHangfireDashboard();
         app.UseHangfireServer(); 
         ...
 }

But when I run my projet in debug and trigger a recurringjob, it never use my customer job activator and instantiate new class…
My recurring job

RecurringJob.AddOrUpdate<MailboxDatabasesManager>("HE_RefreshDBEval", (x) => x.RefreshDatabaseEval(), Cron.MinuteInterval(30));

So, I can’t manage the retriving of “MailboxDatabasesManager” in my custom activator.

It’s same with a simple BackgroundJob.Enqueue((x) => x.func());

How to fix that?

Thx

Hi,
I met the same problems with your a few day ago, and I find the way to solve thi issues.

My code like that:

 public class ServiceJobActivator : JobActivator
    {
        readonly IServiceScopeFactory _serviceScopeFactory;
        public ServiceJobActivator(IServiceScopeFactory serviceScopeFactory)
        {
            if (serviceScopeFactory == null) throw new ArgumentNullException(nameof(serviceScopeFactory));
            _serviceScopeFactory = serviceScopeFactory;
        }

        public override JobActivatorScope BeginScope(JobActivatorContext context)
        {
            return new ServiceJobActivatorScope(_serviceScopeFactory.CreateScope());
        }
    }

 public class ServiceJobActivatorScope : JobActivatorScope
{
    readonly IServiceScope _serviceScope;
    public ServiceJobActivatorScope(IServiceScope serviceScope)
    {
        if (serviceScope == null) throw new ArgumentNullException(nameof(serviceScope));
        _serviceScope = serviceScope;
    }
    public override object Resolve(Type type)
    {
           return  _serviceScope.ServiceProvider.GetService(type);
    }
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
 {
         GlobalConfiguration.Configuration.UseActivator(new ServiceJobActivator(serviceProvider.GetService<IServiceScopeFactory>()));
         app.UseHangfireDashboard();
         app.UseHangfireServer(); 
         ...
 }

So,you need implement JobActivator and JobActivatorScope.

2 Likes

Thank you for your solution, it’s working fine :slight_smile:

Hi,
Sorry,my previous answer is not proper for your question.Recently,I found the library has own the JobActivator for AspNetCore that is named AspNetCoreJobActivator.So,you could use it instead of yours.Or,it’s okay to use your.:slightly_smiling_face:
The AspNetCoreJobActivator code is blelow.

var serviceScopeFactory = serviceProvider.GetService<IServiceScopeFactory>();
GlobalConfiguration.Configuration.UseActivator(new AspNetCoreJobActivator(serviceScopeFactory));
1 Like

This solution is almost correct, it is just missing a disposal of the scope after the job finishes. Add an override for DisposeScope() into ServiceJobActivatorScope like this

public class ServiceJobActivatorScope : JobActivatorScope
    {
        readonly IServiceScope _serviceScope;
        public ServiceJobActivatorScope( IServiceScope serviceScope )
        {
            if( serviceScope == null )
            {
                throw new ArgumentNullException( nameof( serviceScope ) );
            }

            _serviceScope = serviceScope;
        }

        public override object Resolve( Type type )
        {
            return _serviceScope.ServiceProvider.GetService( type );
        }

        public override void DisposeScope( )
        {
            _serviceScope.Dispose( );
            base.DisposeScope( );
        }
    }