Using Hangfire with an IoC collection of jobs only runs the first one registered

Hi

We are using HangFire with Castle/Windsor and a CollectionResolver that resolves all IMonitorJob to their concrete implementations and then uses the RegisterJob.AddOrUpdate in a foreach loop on the collection calling their Execute method, like so…

// NOTES: 
//  _monitorJobs is an IEnumerable<IMonitorJob>
//  IMonitorJob is a simple interface with a single method 
//		void Execute();

var cron = string.Format("*/{0} * * * *", _settings.MonitoringInterval);

foreach (var monitorJob in _monitorJobs)
{
	var jobType = monitorJob.GetType().ToString();
	Logger.DebugFormat("Registering job :: {0}", jobType);
	RecurringJob.AddOrUpdate(jobType,() => monitorJob.Execute(), cron);
}

I see the jobs registered in the database but they are all of type IMonitorJob not their concrete types and when the schedule triggers, only the first registered job executes.

Is there any way I can make sure it registers the job as its concrete type not its interface?

Thanks

James

Hello, current object type in expression () => monitorJob.Execute() is not being evaluated, and the callExpression.Method.DeclaringType is being used as a background job type. You can use the following workaround:

var manager = new RecurringJobManager();

var type = monitorJob.GetType();
var method = type.GetMethod("Execute");
var job = new Job(type, method);

manager.AddOrUpdate(type.Name.ToString(), job, cron);

Hi,

Thanks for the quick reply, that all registers fine and fires correctly.

But it looks llike it now can’t work backwards in Castle to get the correct component.

Castle.MicroKernel.ComponentNotFoundException: No component for supporting the service Calumo.Cloud.Management.Core.InjectedServices.Service.Jobs.CustomerMonitorJob was found
at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Resolve(Type service)
at Hangfire.Windsor.WindsorJobActivator.ActivateJob(Type jobType)
at Hangfire.Common.Job.Activate(JobActivator activator)

I’ll plug away at this and see if I can’t find an answer, but i think I might not be able to use the CollectionResolver with HangFire.

James.

You are welcome. I answered quickly because you are a lucky guy :slight_smile: Hope today I’ll answer other questions as well.

Regarding to the topic, now Windsor is requesting concrete types, you are right. So, you should update your registrations to support concrete type resolving. I don’t know how it is implemented in Windsor, in Autofac it looks like this:

build.Register(x => new CustomerMonitorJob())
    .As<IMonitorJob>() // To be able to resolve all registered implementors
    .As<CustomerMonitorJob>(); // or .AsSelf(), this is the main line for you