Search code examples
c#asp.net-mvchangfire

Error while creating recurring job using Hangfire


I'm trying to use Hangfire in my application to fetch( from external APIs) currency conversion rates on a daily basis and insert in application database. Successfully configured ( think so ) and the Hangfire Tables are created in the DB and the Job table is having entries but the Job is not successfully executed and while checking the State Table it shows failed and have an error message like

{"FailedAt":"2017-10-12T07:55:00.3075439Z",
  "ExceptionType":"System.MissingMethodException",
  "ExceptionMessage":"Cannot create an instance of an interface.",
  "ExceptionDetails":"System.MissingMethodException: Cannot create an instance of an interface.\r\n  
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)\r\n  
    at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n  
     at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n 
       at System.Activator.CreateInstance(Type type, Boolean nonPublic)\r\n   at System.Activator.CreateInstance(Type type)\r\n   at Hangfire.JobActivator.ActivateJob(Type jobType)\r\n   
       at Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type)\r\n   at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)\r\n   
       at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.<PerformJobWithFilters>b__0()\r\n   
       at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)\r\n   
       at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_1.<PerformJobWithFilters>b__2()\r\n   
       at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)\r\n   
       at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)\r\n   
       at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)"}

Code used :

    public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ConfigureAuth(app);
 GlobalConfiguration.Configuration.UseSqlServerStorage("ERPContext");

                RecurringJob.AddOrUpdate<IAPIRequest>(x => x.ProcessCurrencyConversion(), Cron.MinuteInterval(1));
                app.UseHangfireDashboard();
                app.UseHangfireServer();

            }
        }

Interface and Class which has the Method to executed

 public interface IAPIRequest
    {
        void ProcessCurrencyConversion();
    }

 public class APIRequest : IAPIRequest
    {
        public void ProcessCurrencyConversion()
        {
           WebClient client = new WebClient();

            string urlPattern = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22USDKWD,EURKWD,GBPKWD,AEDKWD,ZARKWD%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";

            var jsonResult = client.DownloadString(urlPattern);
            dynamic results = JsonConvert.DeserializeObject<dynamic>(jsonResult);
            var rates = results.rate;
            List<CurrencyJSON> currencies = new List<CurrencyJSON>();
            using (var db = new ERPContext())
            {

                foreach (var rate in rates)
                {
                    var currencyJson = new CurrencyJSON();//POCO
                    currencyJson.Bid = rate.Bid;
                    currencyJson.Name = rate.Name;

                    currencies.Add(currencyJson);
                }

                db.Configuration.AutoDetectChangesEnabled = false;
                db.Configuration.ValidateOnSaveEnabled = false;

                db.CurrencyJson.ToList().AddRange(currencies);
                db.SaveChanges();
            }
        }
    }

What am I doing wrong? Appreciate any help , Thanks in advance . Have already checked similar question posted here but didn't help .


Solution

  • As @Diado pointed out in the comments, HangFire needs a IoC if using an Interface as there is no default support. Or you can use the Class directly instead of an interface.

    https://github.com/devmondo/HangFire.SimpleInjector is one of the IoC injector which I used .