Tuesday, October 15, 2019

HangFire Ioc Contaner - Job Schedular

Nuget :
Hangfire.AspNetCore
Hangfire.SqlServer (Redis can also be used)

services.AddHangfire(x => {
                var options = new SqlServerStorageOptions
                {
                    PrepareSchemaIfNecessary = true,
                    QueuePollInterval = TimeSpan.FromSeconds(5)
                };
                x.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection"), options);
                });


 //services.AddHangfire(configuration => {
            //    configuration.UseStorage(
            //        new MySqlStorage(
            //            "server=127.0.0.1;uid=root;pwd=root;database={0};Allow User Variables=True",
            //            new MySqlStorageOptions
            //            {
            //                TablesPrefix = "Hangfire"
            //            }
            //        )
            //    );
            //};


//https://docs.hangfire.io/en/latest/configuration/using-sql-server.html
            //https://docs.hangfire.io/en/latest/configuration/
            //https://docs.hangfire.io/en/latest/getting-started/aspnet-core-applications.html
            GlobalConfiguration.Configuration.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection"));
            GlobalConfiguration.Configuration.UseActivator(new ServiceJobActivator(serviceProvider.GetService<IServiceScopeFactory>(), serviceProvider));
            //GlobalConfiguration.Configuration.UseActivator(new HangfireActivator(serviceProvider));
            app.UseHangfireDashboard("/hangfire", new DashboardOptions
            { 
                
            });
            app.UseHangfireServer(new BackgroundJobServerOptions { 
                 WorkerCount= 1
            });

Job Activator
public class ServiceJobActivator : JobActivator
    {
        readonly IServiceScopeFactory _serviceScopeFactory;
        private readonly IServiceProvider _serviceProvider;

        public ServiceJobActivator(IServiceScopeFactory serviceScopeFactory, IServiceProvider serviceProvider)
        {
            if (serviceScopeFactory == null) throw new ArgumentNullException(nameof(serviceScopeFactory));
            _serviceScopeFactory = serviceScopeFactory;
            _serviceProvider = serviceProvider;
        }

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

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


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);
        }
    }


In the service, inject IBackgroundJobClient backgroundJobs and use 
_backgroundJobs.Enqueue<ISampleService>(s => s.CallFunction());