'ILogger injected via constructor for Http trigger functions with Azure Function 2.x
ILogger can be injected to function parameter, like Token method below.
However, the error below occurred when it is injected to constructor parameter log.
[07/03/2019 17:15:17] Executed 'Token' (Failed, Id=4e22b21f-97f0-4ab4-8f51-8651b 09aedc8) [07/03/2019 17:15:17] Microsoft.Extensions.DependencyInjection.Abstractions: Una ble to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'Functions'.
ILogger can be injected to Token function parameter below. But the error above occurred when it is injected to constructor parameter log.
public class Functions
{
private HttpClient _httpClient;
private IAppSettings _appSettings;
private ILogger _log;
public Functions(HttpClient httpClient, IAppSettings appSettings //working for these two
, ILogger log //not working, errors
)
{
_log = log;
}
[FunctionName("Token")]
public async Task<IActionResult> Token(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Token")]
HttpRequest httpRequest,
ILogger log)
{
}
}
Dependence injection below
[assembly: WebJobsStartup(typeof(Startup))]
namespace MyApp
{
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddTransient<IAppSettings, AppSettings>();
//builder.Services.AddLogging(); //not working
//builder.Services.AddSingleton<ILogger>() //not working
}
}
Visual studio 2017
Solution 1:[1]
Calling LogCategories.CreateFunctionUserCategory fixed my problem. Complete example:
Azure Functions Core Tools (2.7.1158 Commit hash: f2d2a2816e038165826c7409c6d10c0527e8955b)
Function Runtime Version: 2.0.12438.0
Startup.cs
No need to add
builder.Services.AddLogging();it's imported automatically in the container.
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyFunctionsNamespace.Startup))]
namespace MyFunctionsNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IMyService, MyService>();
}
}
}
MyFunkyFunction.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace MyFunctionsNamespace
{
public class MyFunkyFunction
{
private readonly IMyService _myService;
public MyFunkyFunction(IMyService myService)
{
_myService = myService;
}
[FunctionName("FunkyFunc")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
HttpRequest req
, ILogger log
)
{
log.LogInformation("C# HTTP trigger function processed a request.");
_myService.Do();
return new OkObjectResult("Hello");
}
}
}
IMyService.cs
Anything in
LogCategories.CreateFunctionUserCategorywill do the job. It seems to be some WebJob legacy requirement.
using Microsoft.Azure.WebJobs.Logging;
using Microsoft.Extensions.Logging;
namespace MyFunctionsNamespace
{
public interface IMyService
{
void Do();
}
public class MyService : IMyService
{
private readonly ILogger _log;
public MyService(ILoggerFactory loggerFactory)
{
// Important: Call CreateFunctionUserCategory, otherwise log entries might be filtered out
// I guess it comes from Microsoft.Azure.WebJobs.Logging
_log = loggerFactory.CreateLogger(LogCategories.CreateFunctionUserCategory("Common"));
}
public void Do()
{
_log.Log(LogLevel.Information, "Hello from MyService");
}
}
}
Solution 2:[2]
If you want to get away with not using LoggerFactory then you need to change "ILogger log" to "ILogger log".
public class Functions
{
private HttpClient _httpClient;
private IAppSettings _appSettings;
private ILogger _log;
public Functions(HttpClient httpClient, IAppSettings appSettings
, ILogger<Program> log
)
{
_log = log;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Milen Stefanov |
| Solution 2 | tank104 |
