Search code examples
azureninjectazure-webjobs

Microsoft.Azure.WebJobs.Host.FunctionInvocationException


I'm getting this error in my Azure WebJob. Any idea what may be causing it?

I'm using Ninject to handle DI in my Azure WebJobs console app.

I've already set the Bind statements for all my services. Services call repositories. Do I need to bind repositories as well?

When I run the WebJob, it picks up the message in the queue but fails with the following message. I think this is related to Ninject.

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> 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.CreateInstanceT at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstanceT at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory1.Create() at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker1.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__31.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__2c.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext() --- End of inner exception stack trace --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__1.MoveNext()

Here's the Program class:

class Program
{
   static readonly IKernel Kernel = new StandardKernel();
   static JobHostConfiguration config;

   static void Main()
   {
      BootStrapIoc();
      var host = new JobHost();

      // The following code ensures that the WebJob will be running continuously
      host.RunAndBlock();
    }

    private static void BootStrapIoc()
    {
       Kernel.Load(Assembly.GetExecutingAssembly());
       config = new JobHostConfiguration
       {
          JobActivator = new MyJobActivator(Kernel)
       };
     }
}

Here's MyJobActivator

public class BrmJobActivator : IJobActivator
{
   private readonly IKernel _container;

   public MyJobActivator(IKernel container)
   {
      _container = container;
   }

   public T CreateInstance<T>()
   {
      return _container.Get<T>();
   }
}

Here's Ninject Bindings:

public class NinjectBindings : Ninject.Modules.NinjectModule
    {
        public override void Load()
        {
            Bind<IConfiguration>().ToMethod(ctx => {
                var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json");
                IConfigurationRoot Configuration = builder.Build();
                return Configuration;
            });

            Bind<IAccountsServices>().To<AccountsServices>();
            Bind<IBlogServices>().To<BlogServices>();

            // Bind<IAccountsRepository>().To<AccountsRepository>();
            // Bind<IBlogsRepository>().To<BlogsRepository>();
        }
    }

Solution

  • According to the error message, "System.MissingMethodException: No parameterless constructor defined for this object", it seems that you miss parameter config for ininitializing JobHost in the main function.

    If it is that case, please use the following code in the main function. It works correctly.

    JobHost  host = new JobHost(config)
    

    While without config parameter to initializing JobHost then I got the same error message.

    enter image description here

    The following is my detail steps:

    In the main function, changed code as following:

    IKernel Kernel = new StandardKernel();
    Kernel.Load(Assembly.GetExecutingAssembly());
    var config = new JobHostConfiguration
    {
         JobActivator = new MyJobActivator(Kernel)
    };
    var host = new JobHost(config);
    host.RunAndBlock();
    

    I create the demo with your code supplied and change class name BrmJobActivator to MyJobActivator. And in the NinJect Bindings.cs load function just keep following codes:

      Bind<IAccountsServices>().To<AccountsServices>();
      Bind<IBlogServices>().To<BlogServices>();
    

    Then it works correctly for me.

    enter image description here