简体   繁体   中英

How to Setup Hangfire using Asp.Net 4.7 and DI with Microsoft.Extensions.DependencyInjection?

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!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM