Hangfire 1.5.3 System.MissingMethodException on all our jobs

北慕城南 提交于 2019-12-12 17:14:43

问题


We just updated hangfire from 1.3.4 to 1.5.3.

Our startup has changed from this:

    private static void DoHangfire(IAppBuilder app)
    {
        var options = new BackgroundJobServerOptions
        {
            // Set thread count to 1
            WorkerCount = 1
        };

        app.UseHangfire(config =>
        {
            config.UseSqlServerStorage(ConfigurationManager.ConnectionStrings["JobsDB"].ConnectionString);
            config.UseAuthorizationFilters(new HangfireDashboardAuthorizationFilter());
            config.UseServer(options);
        });

        // Set retries to zero
        GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });

        JobActivator.Current = new WindsorJobActivator(Container.Kernel);
    }

to this:

    private static void DoHangfire(IAppBuilder app)
    {
        var options = new BackgroundJobServerOptions
        {
            // Set thread count to 1
            WorkerCount = 1
        };

        GlobalConfiguration.Configuration.UseSqlServerStorage(
            ConfigurationManager.ConnectionStrings["JobsDB"].ConnectionString);

        app.UseHangfireDashboard("/hangfire", new DashboardOptions()
                                                  {
                                                      AuthorizationFilters = new List<IAuthorizationFilter>
                                                                                 {
                                                                                     new HangfireDashboardAuthorizationFilter()
                                                                                 }
                                                  });

        app.UseHangfireServer(options);

        // Set retries to zero
        GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });

        JobActivator.Current = new WindsorJobActivator(Container.Kernel);
    }

Now all our jobs (we have 4 different kinds of jobs) fail immediately with this error:

System.MissingMethodException: No parameterless constructor defined for this object. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type) at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context) at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass3.b__0() at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func1 continuation) at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable1 filters) at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context) at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)


回答1:


Well the problem had to do with some magic in how the new version of Hangfire interacted with the Hangfire.Windsor package, which simply provides a custom JobActivator with a windsor container for service location.

By moving the

JobActivator.Current = new WindsorJobActivator(Container.Kernel);

above the call to app.UseHangfireServer() we were able to uncover the real exception message, which was a Castle.MicroKernel.ComponentNotFoundException informing us that it couldn't wire in the dependency containing the method we wanted hangfire to run.

Suffice to say, in 1.3.4, to run a job you can do this:

BackgroundJob.Enqueue(() => thingWhichDoesStuff.DoStuff()); 

where thingWhichDoesStuff is injected into the containing class and the hangfire.windsor JobActivator is just magically able to resolve to the type.

However in 1.5.3 this magic resolution no longer happens, so you must explicitly tell the JobActivator the interface of the type containing the method you want hangfire to run:

BackgroundJob.Enqueue<IDoStuff>(x => x.DoStuff());  

This causes all our jobs to start working again.



来源:https://stackoverflow.com/questions/35088769/hangfire-1-5-3-system-missingmethodexception-on-all-our-jobs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!