【问题标题】:Inject instance of ILogger in my component class Azure Functions using Autofac使用 Autofac 在我的组件类 Azure Functions 中注入 ILogger 实例
【发布时间】:2018-08-28 07:06:33
【问题描述】:

我正在编写一个简单的 Azure 函数。

我已经安装了AzureFunctions.Autofac nuget 包,并希望将其用作我的DI 库。

我设置了以下AutofacConfig 类来注册我的类型:

public class AutofacConfig
{
    public AutofacConfig(string functionName)
    {
        DependencyInjection.Initialize(builder =>
        {
            //do all of you initialization here

            //db client
            builder.RegisterType<EventComponent>()
            .As<IComponent<EventModel>>().SingleInstance(); 
        }, functionName);
    }
}

这是我的EventComponent 类,我想向其中注入提供的ILogger 实例。

public class EventComponent : IComponent<EventModel>
{
    private ILogger _log;

    public EventComponent(ILogger logger)
    {
        _log = logger;
    }
}

这是我注入 EventComponent 的方式:

[FunctionName("AddEvent")]
    public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, ILogger log, [Inject]IComponent<EventModel> component)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        await component.Add(new EventModel() { Id = Guid.NewGuid(), Description = $"Test description nr: {new Random().Next(1, 100000)}", User = "Test User" });

        return req.CreateResponse(HttpStatusCode.OK);
    }

问题是,我在上面遇到了一个异常,因为Autofac 无法解析参数 Microsoft.Extensions.Logging.ILogger。

这是异常消息:

异常绑定参数“组件”...无法解析构造函数“Void .ctor(Microsoft.Extensions.Logging.ILogger)”的参数“Microsoft.Extensions.Logging.ILogger logger”。 (有关详细信息,请参阅内部异常。)-> 无法使用可用的服务和参数调用类型为 'Event.Function.Components.EventComponent' 的具有 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 的构造函数:\r \n无法解析构造函数'Void .ctor(Microsoft.Extensions.Logging.ILogger)'的参数'Microsoft.Extensions.Logging.ILogger logger'。",

如何将ILogger 实例注入我的EventComponent 类?

【问题讨论】:

  • 您是否尝试过使用builder.RegisterType&lt;Logger&gt;().As&lt;ILogger&gt;().SingleInstance();?显然,您需要注册一个记录器,并且应该使用 autofac 构建器并在注册 EventComponent 类之前进行。
  • @JohnEphraimTugado Logger 代表什么?我没有 Logger 类,如果我想使用 Intellisense 提供的默认 Logger 类,我需要将 Type 传递给通用 Logger 类
  • 您需要传递ILogger 的实现,它可以是您自己的实现。您也可以查看this的答案作为参考。
  • 当您不熟悉ILogger 本身时,为什么还要在EventComponent 类中使用ILogger?不能删除引用吗?
  • @JohnEphraimTugado .NET SDK 为 ILogger 提供了一个默认实现,它记录到 Application Insights,我想在我的组件类中使用默认日志记录。

标签: c# autofac azure-functions autofac-configuration


【解决方案1】:

在 Azure Functions V2 中,默认情况下会注入 ILogger。另外,这里有两篇关于 Azure Functions 中依赖注入的非常好的文章。 https://blog.mexia.com.au/dependency-injections-on-azure-functions-v2

http://codingsoul.de/2018/01/19/azure-function-dependency-injection-with-autofac/

【讨论】:

    【解决方案2】:

    我在寻找同样的东西时发现了你的问题。你找到解决办法了吗?

    因为我认为这是不可能的。 ILogger 日志是由框架注入的,我看不到如何从您的 AutofacConfig 类中引用它。

    我如何解决这个问题是通过将 EventComponent-class 更改为使用 Setter-injection 而不是 Constructor-injection,如下所示:

    public class EventComponent : IComponent<EventModel>
    {
        public ILogger Log { get; set; }    
    }
    

    并更改您的功能以设置日志属性:

    [FunctionName("AddEvent")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, ILogger log, [Inject]IComponent<EventModel> component)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            component.Log = log;
            await component.Add(new EventModel() { Id = Guid.NewGuid(), Description = $"Test description nr: {new Random().Next(1, 100000)}", User = "Test User" });
    
            return req.CreateResponse(HttpStatusCode.OK);
        }
    

    缺点是您需要记住在使用该类的每个函数的开头设置该值,但注入有效。

    【讨论】:

      【解决方案3】:

      如果您想将 ILogger 注入到函数应用中,您需要执行以下操作:

      1. 将正确的日志级别和命名空间添加到您的 host.json

         {
            "version": "2.0",
            "logging": {
                 "applicationInsights": {
                     "samplingSettings": {
                         "isEnabled": true
               }
             },
            "logLevel": {
                "YourNameSpace": "Information"
         }    
        
      2. Inject ILogger&lt;T&gt; 其中 T 是您的函数应用类名称/类型。在此示例中,我的函数应用类名称是 Api。

         public class TestService : ITestService
         {
             private readonly ILogger<Api> _logger;
        
             public TestService(ILogger<Api> logger)
             {
                 _logger = logger;
             }
        
             public void LogSomething(string message)
             {
                 _logger.LogInformation(message);
             }
         }
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-03
        • 1970-01-01
        • 2020-07-16
        • 2020-03-04
        • 2015-06-21
        • 2016-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多