No parameterless constructor error in WebJobs with .NET Core and Ninject

922 Views Asked by At

I'm trying to do a bit of a balancing act here. Currently Azure WebJobs don't support .NET Core.

With some help, I created a .NET Core Console App and made it work as a WebJob. On top of that I'm trying to implement Ninject for DI.

Code compiles fine but when I run it, I'm getting the "No parameterless constructor is defined for this object." error -- see below.

enter image description here

I may be in a bit of unchartered territory here with Azure WebJobs, .NET Core 2.0 and Ninject but any idea what may be causing this?

BTW, I had the same exact code running as a WebJob targeting .NET Framework. I needed to migrate to .NET Core 2.0 because I'm using class libraries that target .NET Core 2.0. I'm also using DI in those class libraries which is why I'm trying to migrate my WebJob to .NET Core 2.0 using Ninject.

P.S. I'm using Azure.WebJobs 3.0.0 beta2 to convert my .NET Core console app to WebJobs. I'm also using Ninject 3.2.2

UPDATE: Here's my code for the JobActivator

public class BrmJobActivator : IJobActivator
    {
        private readonly IKernel _container;

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

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

And here's the main Program:

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

        static void Main(string[] args)
        {
            Environment.SetEnvironmentVariable("AzureWebJobsDashboard", "MySettings");
            Environment.SetEnvironmentVariable("AzureWebJobsStorage", "MySettings");

            BootStrapIoc();

            config = new JobHostConfiguration();

            if (config.IsDevelopment)
            {
                config.UseDevelopmentSettings();
            }

            var host = new JobHost(config);
            host.RunAndBlock();
        }

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

UPDATE 2: I'm now getting the following error.

enter image description here

This error is thrown at the following line -- also see second image. return _container.Get<T>();

enter image description here

UPDATE 3: Here's the code in Functions.cs file:

public class Functions
{

   private static ISomeService1 _someService1;
   private static ISomeService2 _someService2;

   private static IConfiguration _configuration;


   public Functions(ISomeService1 someService1, ISomeService2 someService2, IConfiguration configuration)
   {
       _someService1 = someService1;
       _someService2 = someService2;
       _configuration = configuration;
    }

    public async Task ProcessQueueMessage([QueueTrigger("my-brm-queue")] QueueMessage message, TextWriter log)
    {

        // Consume service
        _someService1.DoSomething(message);

    }

}

UPDATE 4: Here's the code in Ninject bindings class:

public class NinjectBindings : Ninject.Modules.NinjectModule
{
   IConfiguration Configuration;

   public override void Load()
   {
       // Bind to IConfiguration
       var builder = new ConfigurationBuilder();
       builder.SetBasePath(Directory.GetCurrentDirectory());
       builder.AddJsonFile("appsettings.json");
       Configuration = builder.Build();
       Bind<IConfiguration>().ToMethod(ctx => {
          return Configuration;
       });

       // Create instances of clients
       var docDbClient = new ClassLibrary1.DocumentDbClient(Configuration);
       var tsClient = new ClassLibrary2.TableStorageClient(Configuration);

       // Bind Services
       Bind<ISomeService1>().To<SomeService1>();
       Bind<ISomeService2>().To<SomeService2>();

       // Bind Repositories
       Bind<IRepository1>().To<Repository1>();
       Bind<IRepository2>().To<Repository2>();

   }
}
1

There are 1 best solutions below

4
On

After instantiating the JobHostConfiguration from the BootStrapIoc method, you re-instantiate it from the main method.

Just remove this line in your main method:

config = new JobHostConfiguration();