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

时间:2019-02-26 00:30:08

标签: c# azure dependency-injection azure-functions

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

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.
    }
}

我在要从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>();
        }
   }

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

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

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

问题

如何在ILogger中设置IWebJobsStartup的注入?

5 个答案:

答案 0 :(得分:6)

我设法解决了这个问题:

按如下方式插入我的班级:

MyClass.cs:

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

    public MyClass(ILogger<MyClass> logger)
    {
        _logger = logger;
    }
}

Startup.cs:

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

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

答案 1 :(得分:3)

更新

引用Use dependency injection in .NET Azure Functions

  

注册服务

     

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

     

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

所以在这种情况下

[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    
        }
    }
}

原始

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

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
}

,并且在函数的构造函数中有一个ILoggerFactory

//...

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

//...

答案 2 :(得分:1)

您应该从启动类中删除对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;
}
Azure Functions Runtime 2.0.12265起, zure函数现在支持

实例方法

enter image description here

答案 3 :(得分:0)

您可以添加

  "logging": {
    "fileLoggingMode": "debugOnly",
    "logLevel": {
      "default": "Information"
    }
  }

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

答案 4 :(得分:0)

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

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "FunctionProjectNameSpace.RegisteredClass": "Information"
    }
  }
}

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