如何使用IWebJobsStartup使用新的DI将ILogger注入到Azure函数中?

Kzr*_*tof 9 c# dependency-injection azure azure-functions

我正在使用Azure Functionv2。这是我使用构造函数注入的函数:

public sealed class FindAccountFunction
{
    private readonly IAccountWorkflow m_accountWorkflow;

    private readonly IMapper m_mapper;

    private readonly ILogger m_logger;

    public FindAccountFunction(ILogger logger, IMapper mapper, IAccountWorkflow accountWorkflow)
    {
        m_logger = logger;
        m_mapper = mapper;
        m_accountWorkflow = accountWorkflow;
    }

    [FunctionName("FindAccount")]
    public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, Verbs.Get, Route = "v1/accounts/")] HttpRequest httpRequest, ILogger logger)
    {
        // Do stuff.
    }
}
Run Code Online (Sandbox Code Playgroud)

我在派生自IWebJobsStartup以下类的Startup类中声明了要注入到Azure函数中的所有依赖项:

    public sealed class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder webJobsBuilder)
        {
            //  Registers the application settings' class.
            webJobsBuilder.Services.AddSingleton<IApplicationSettings, ApplicationSettings>();

            //  ** Registers the ILogger instance **
            //  ** ?? **

            //  Registers the IMapper instance for the contracts.
            var mapperConfiguration = new MapperConfiguration(cfg => cfg.AddProfile(new MyProfile()));

     webJobsBuilder.Services.AddSingleton(mapperConfiguration.CreateMapper());

            // Registers custom services.
            webJobsBuilder.Services.AddTransient<IStorageService, StorageService>();

            webJobsBuilder.Services.AddTransient<IAccountWorkflow, AccountWorkflow>();
        }
   }
Run Code Online (Sandbox Code Playgroud)

Azure函数调用也依赖于ILogger的其他注入服务,例如IAccountWorkflow

public sealed class AccountWorkflow : IAccountWorkflow
{  
    public AccountWorkflow(ILogger logger, IStorageService storageService)
    {
        if(logger is null)
            throw new ArgumentNullException();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题在于,ILogger由于ILogger注入了null ,因此DI无法找到任何实现,并且无法解析服务。

如何设置ILoggerin 的注入IWebJobsStartup

jho*_*ops 12

我设法解决了这个问题:

注入我的课程如下:

MyClass.cs:

public class MyClass
{
    private readonly ILogger<MyClass> _logger;

    public MyClass(ILogger<MyClass> logger)
    {
        _logger = logger;
    }
}
Run Code Online (Sandbox Code Playgroud)

启动.cs:

[assembly: FunctionsStartup(typeof(Namespace.Startup))]   

namespace Namespace {    
public class Startup : FunctionsStartup 
{
    public override void Configure(IFunctionsHostBuilder builder) 
    {
        builder.Services.AddLogging(); 
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用。然而,重要的是像``ILogger&lt;MyClass&gt; _logger```而不是``ILogger _logger```那样注入它 (7认同)

小智 8

你可以加

  "logging": {
    "fileLoggingMode": "debugOnly",
    "logLevel": {
      "default": "Information"
    }
  }
Run Code Online (Sandbox Code Playgroud)

如果您想使用IloggerFactory,则无需添加DI


Nko*_*osi 7

更新

.NET Azure函数中的参考使用依赖项注入

注册服务

要注册服务,您可以创建一个configure方法并将组件添加到IFunctionsHostBuilder 实例。Azure Functions主机创建一个IFunctionsHostBuilder ,并将其直接传递到您配置的方法中。

要注册您的configure方法,您必须添加一个程序集属性,该FunctionsStartup属性使用该属性为您的configure方法指定类型 。

所以在这种情况下

[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]    
namespace MyNamespace {
    public class Startup : FunctionsStartup {
        public override void Configure(IFunctionsHostBuilder builder) {
            //  ** Registers the ILogger instance **
            builder.Services.AddLogging();

            //  Registers the application settings' class.
            //...

            //...omitted for brevity    
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

原版的

我相信,由于您有权访问服务集合,因此您应该能够向其中添加日志记录

public void Configure(IWebJobsBuilder webJobsBuilder) {       

    //  ** Registers the ILogger instance **
    webJobsBuilder.Services.AddLogging();

    //OR
    //webJobsBuilder.Services.AddLogging(builder => {
    //    //...
    //});

    //  Registers the application settings' class.
    //...

    //...removed for brevity
}
Run Code Online (Sandbox Code Playgroud)

ILoggerFactory在函数的构造函数中具有。

//...

//Ctor
public FindAccountFunction(ILoggerFactory loggerFactory, IMapper mapper, IAccountWorkflow accountWorkflow) {
    m_logger = loggerFactory.CreateLogger<FindAccountFunction>();
    m_mapper = mapper;
    m_accountWorkflow = accountWorkflow;
}

//...
Run Code Online (Sandbox Code Playgroud)

  • 感谢您进行更新,但我认为不再需要builder.Services.AddLogging();吗?似乎已经在“服务”集合中进行了设置。 (6认同)
  • 我认为现在这已经有些过时了,应该改用[FunctionsStartup](https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#registering-services)。 (3认同)
  • @Kapé 是正确的。这将在该版本发布之前完成。感谢您提供参考链接。我已经更新了答案以反映最新版本。 (2认同)
  • 使用`ILogger &lt;构造函数的类的名称&gt;可以正常工作。 (2认同)
  • @user3613932 是的,较新的版本默认添加了日志记录,因此使用“ILogger&lt;T&gt;”应该是开箱即用的。 (2认同)
  • 如果在 Azure Functions 控制台中看不到日志,请向 `host.json` 添加以下代码 `"logging": { "logLevel": { "default": "Information" } }` (2认同)

Nic*_*coD 6

您应该AddLogging从启动类中删除对方法的调用。默认记录器已由azure功能主机设置。

[assembly: WebJobsStartup(typeof(StartUp))]
public class StartUp : IWebJobsStartup
{
    public void Configure(IWebJobsBuilder builder)
    {
        builder.Services.AddSingleton<AppSettings>();

        builder.Services.AddTransient<IMyService, MyService>();
    }
}

public MyFunction(IMyService service, ILogger<IMyService> logger)
{
    this.service = service;
    this.logger = logger;
}
Run Code Online (Sandbox Code Playgroud)

Azure Functions Runtime 2.0.12265开始,azure函数现在支持实例方法

在此处输入图片说明

  • @Kzrystof 将以下代码添加到 `host.json` 中 ```"logging": { "logLevel": { "default": "Information" } }``` (4认同)
  • 我没有任何错误,但是没有看到以前使用过的日志(在“ Azure函数”监视器部分或“ App Insights”中)...需要更多调查以确保它能正常工作 (3认同)

小智 5

除了在函数 Startup 类中注册类之外,我们还需要在host.json文件中添加命名空间,以便将消息记录到应用洞察中。如果我们不添加它,它只会将消息记录到本地控制台,但是当部署在 azure 上时,它不会记录任何内容,也不会给出任何错误。

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "FunctionProjectNameSpace.RegisteredClass": "Information"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

此处的示例代码供参考 - https://gist.github.com/nareshnagpal06/82c6b4df2a987087425c32adb58312c2