Reputation: 985
I would like to use DI in my WebJobs same way I use in WebApps but honestly I don't know how Functions.cs is called. If I insert a Console.WriteLine inside Functions.cs's constructor it is not printed.
How could I make this work?
Program.cs
class Program
{
static void Main(string[] args)
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
});
builder.ConfigureLogging((context, b) => {
b.AddConsole();
});
builder.ConfigureServices((context, services) => {
// Inject config
services.Configure<Secrets.ConnectionStrings>(context.Configuration.GetSection("ConnectionStrings"));
services.AddSingleton<Functions>();
services.AddSingleton<MyEmail>();
services.AddSingleton<IMyFunc, MyFunc>();
services.BuildServiceProvider();
});
var host = builder.Build();
using (host)
{
host.Run();
}
}
}
Functions.cs
public class Functions
{
private static IOptions<Secrets.ConnectionStrings> _myConnStr;
private static MyEmail _myEmail;
private static IMyFunc _myFunc;
public Functions(IOptions<Secrets.ConnectionStrings> ConnectionString, MyEmail MyEmail, MyFunc MyFunc)
{
_myConnStr = ConnectionString;
_myEmail = MyEmail;
_myFunc = MyFunc;
Console.WriteLine("Functions constructor");
}
public static void ProcessQueueMessage
(
[QueueTrigger("teste")]
string message,
ILogger logger
)
{
// use my injected stuff
}
}
Thank you very much.
Upvotes: 0
Views: 1876
Reputation: 247551
If using dependency injection via constructor with your function then the function itself needs to be an instance member and not static member.
Your constructor is not being called in your example because the function is static and is thus there is no need to call the instance constructor
public class Functions {
private readonly IOptions<Secrets.ConnectionStrings> connectionStrings;
private readonly MyEmail myEmail;
private readonly IMyFunc myFunc;
public Functions(IOptions<Secrets.ConnectionStrings> connectionStrings, MyEmail myEmail, MyFunc MyFunc) {
this.connectionString = connectionStrings;
this.myEmail = myEmail;
this.myFunc = myFunc;
Console.WriteLine("Functions constructor");
}
public void ProcessQueueMessage(
[QueueTrigger("teste")]
string message,
ILogger logger
) {
// use my injected stuff
}
}
From there it is just a matter of following the details from documentation
Upvotes: 1
Reputation: 1777
Azure fuctions work a bit different than you are used to. You can do something like the following below:
using System;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Logging;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton((s) => {
return new MyService();
});
builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
}
}
}
You can read a lot more on Microsoft homepage here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection
Upvotes: 1