ILogger 通过构造函数注入 Azure Function 2.x 的 Http 触发器函数

Pin*_*ong 9 c# azure azure-functions

ILogger可以注入到函数参数中,就像Token下面的方法。

但是,将其注入到构造函数参数时发生了以下错误log

[07/03/2019 17:15:17] 执行“令牌”(失败,Id=4e22b21f-97f0-4ab4-8f51-8651b 09aedc8)[07/03/2019 17:15:17] Microsoft.ExtensionsInject.D抽象:尝试激活“功能”时无法解析“Microsoft.Extensions.Logging.ILogger”类型的服务。

ILogger可以注入Token下面的函数参数。但是当它被注入到构造函数参数时发生了上面的错误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)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

下面的依赖注入

[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
        }
}
Run Code Online (Sandbox Code Playgroud)

视觉工作室 2017

Kzr*_*tof 8

我也有这个问题。我能够通过调用来修复它AddLogging()

[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();
        }
}
Run Code Online (Sandbox Code Playgroud)

然后,在 Azure 函数中,我必须通过 aILoggerFactory而不是 anILoggerILogger从以下位置获取实例loggerFactory

public class Functions
{
    private HttpClient _httpClient;
    private IAppSettings _appSettings;
    private ILogger _log;

    public Functions(HttpClient httpClient, IAppSettings appSettings, ILoggerFactory loggerFactory)
    {
        _log = loggerFactory.CreateLogger<Functions>();
    }

    [FunctionName("Token")]
    public async Task<IActionResult> Token(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Token")]
        HttpRequest httpRequest)
    {
           // No need to keep getting the ILogger from the Run method anymore :)
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 8

打电话LogCategories.CreateFunctionUserCategory解决了我的问题。完整示例:

Azure Functions Core Tools (2.7.1158 Commit hash: f2d2a2816e038165826c7409c6d10c0527e8955b)
Function Runtime Version: 2.0.12438.0
Run Code Online (Sandbox Code Playgroud)

启动文件

无需添加builder.Services.AddLogging();它会自动导入到容器中。

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>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

IMyService.cs

任何东西都LogCategories.CreateFunctionUserCategory可以完成这项工作。这似乎是一些 WebJob 遗留要求。

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • ```LogCategories.CreateFunctionUserCategory()``` 成功了 (2认同)