Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No parameterless constructor defined for this object - Hangfire scheduler

I've just installed Hangfire package in my MVC website. I've created a Startup class

[assembly: OwinStartup(typeof(Website.Startup))]

namespace Website
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            Hangfire.ConfigureHangfire(app);
            Hangfire.InitializeJobs();
        }
    }
}

and a Hangfire class

public class Hangfire
{
    public static void ConfigureHangfire(IAppBuilder app)
    {
        app.UseHangfire(config =>
        {
            config.UseSqlServerStorage("DefaultConnection");
            config.UseServer();
            config.UseAuthorizationFilters(); 
        });
    }

    public static void InitializeJobs()
    {
        RecurringJob.AddOrUpdate<CurrencyRatesJob>(j => j.Execute(), "* * * * *");
    }
}

Also, I've created a new job in a separate class library

public class CurrencyRatesJob
{
    private readonly IBudgetsRepository budgetsRepository;

    public CurrencyRatesJob(IBudgetsRepository budgetsRepository)
    {
        this.budgetsRepository = budgetsRepository;
    }

    public void Execute()
    {
        try
        {
            var budgets = new BudgetsDTO();
            var user = new UserDTO();

            budgets.Sum = 1;
            budgets.Name = "Hangfire";
            user.Email = "[email protected]";

            budgetsRepository.InsertBudget(budgets, user);
        }
        catch (Exception ex)
        {
            var message = ex.ToString();
            throw new NotImplementedException(message);
        }
    }
}

So when I run the application, in the Hangfire's dashboard I get the following error:

Failed An exception occurred during job activation.
System.MissingMethodException

No parameterless constructor defined for this object.

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.ActivateJob(Type jobType)
   at Hangfire.Common.Job.Activate(JobActivator activator)

So, I'm a little lost here. What am I missing?

like image 343
Marian Ene Avatar asked May 04 '15 17:05

Marian Ene


Video Answer


1 Answers

It appears you have not connected Hangfire to the IoC container you are using and therefore it uses its default strategy to create a requested type, which in your specific example means calling:

System.Activator.CreateInstance(typeof(CurrencyRatesJob));

Because the CurrencyRatesJob class does not have a default parameterless constructor, this fails with the error message you show in your question.

To connect Hangfire to your IoC infrastructure, you need to create your own JobActivator class that overrides the ActivateJob method and uses the configured IoC container to create instances of the requested job types.

An example that uses Unity as the container (UnityJobActivator) can be found here and an example for the Funq container (FunqJobActivator) can be found here.

The process is described in the Hangfire documentation, and standard implementations for several container types are available from the Hangfire github repo

like image 133
Alex Avatar answered Sep 24 '22 12:09

Alex