0

I followed this example https://learn.microsoft.com/pt-br/azure/app-service/webjobs-sdk-get-started and it is working fine. What I want to do is to make the connection strings (strongly typed) available in all methods within Functions class. My Connection Strings object:

namespace MyApp.Domain
{
  public class Secrets
  {
    public class ConnectionStrings
    {
      public string SqlServer {get; set;}
      public string Storage {get; set;}
      public string SendGrid {get; set;}
      public string AzureWebJobsDashboard { get; set; }
      public string AzureWebJobsStorage {get; set;}
    }
  }
}

In web project I use (and it works perfectly):

services.Configure<Secrets.ConnectionStrings>(Configuration.GetSection("CUSTOMCONNSTR_ConnectionStrings"));

and in the classes' constructors I use:

public class EmailController: ControllerBase
  {
    private readonly MyEmail _myEmail;

    public EmailController(MyEmail MyEmail)
    {
      _myEmail = MyEmail;
    }

    [HttpGet]
    public async Task<ActionResult<string>> SendEmail()
    {
      try
      {
        ...

        return await _myEmail.SendMailMI3D(myMsg);
      }
      catch (System.Exception ex)
      {
          return ex.Message + " - " + ex.StackTrace;
      }
    }

    [HttpGet("sendgrid")]
    public string GetSendGrid(long id)
    {
      return _myEmail.SendGridConnStr();
    }
  }

But this way doesn't work on webjobs (console apps).

I tried to insert a simple Console.WriteLine in Functions' constructor but it doesn't work as well. So I think this is the problem: Functions' constructor is not being called. So when I insert a message in my queue I receive this error message related to DI Connection String:

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.NullReferenceException: Object reference not set to an instance of an object.

Can anybody please help me? Thanks a lot.

public Functions(IOptions<Secrets.ConnectionStrings> ConnectionStrings)
    {
      _connectionStrings = ConnectionStrings;

      Console.WriteLine("Simple line");
      Console.WriteLine($"Functions constructor: ${_connectionStrings.Value.SendGrid}");
    }

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.NullReferenceException: Object reference not set to an instance of an object.

Joy Wang
  • 39,905
  • 3
  • 30
  • 54
Ricardo Gaefke
  • 823
  • 1
  • 7
  • 21

1 Answers1

0

Dependency Injection is available in WebJobs but you do need to take the extra step to create an IJobActivator to define the injection.

namespace NetCoreWebJob.WebJob
{
    public class JobActivator : IJobActivator
    {
        private readonly IServiceProvider services;

        public JobActivator(IServiceProvider services)
        {
            this.services = services;
        }

        public T CreateInstance<T>()
        {
            return services.GetService<T>();
        }
    }
}

Inside Main()

var config = new JobHostConfiguration();
config.JobActivator = new JobActivator(services.BuildServiceProvider());

That should allow the runtime to utilize the parameterized constructor.

PerfectlyPanda
  • 3,271
  • 1
  • 6
  • 17