在运行Asp.Net Core 2的Webapi 2上使用Serilog的DI ILogger

时间:2018-04-26 10:29:36

标签: c# logging asp.net-core-2.0 serilog

我正在尝试使用Asp.Net Core 2(使用MSSQLServer集成)将Serilog集成到我的WebApi 2中。

我添加了nuget包,然后将以下内容添加到我的

public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

var log = new LoggerConfiguration()
                .WriteTo.MSSqlServer(DbGlobals.DevDatabase, "Logs")
                .CreateLogger();

loggerFactory.AddSerilog(log);

我的Program.cs我有默认值;

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();

从阅读MSDN文档.CreateDefaultBuilder(args)应该包含日志记录吗?

然而,当我然后将ILogger转到我的控制器时;

[Route("api/[controller]")]
public class TraderController : Controller
{
    private TraderService _service;
    private readonly ILogger _logger;

    public TraderController(Func<IBemfeitoDataContext> context, ILogger logger)
    {
        _service = new TraderService(context, logger);
        _logger = logger;
    }

我收到以下错误;

  

InvalidOperationException:无法解析类型&#39; Microsoft.Extensions.Logging.ILogger&#39;的服务。尝试激活WebApi.Controllers.TraderContactController&#39;。

我是否需要在Startup.cs中为ILogger物理设置单例。谁能告诉我这里缺少什么?正如我所假设的那样,因为日志记录已构建到Core管道中,这将是它知道如何解决的问题吗?

2 个答案:

答案 0 :(得分:2)

您需要重构控制器以期望通用记录器 if item_formset.is_valid() == False: return self.render_to_response(self.get_context_data(form=form,item_formset=item_formset )) subTotal=0 i=0 for f in item_formset.forms: subTotal += float(f.data['item-'+str(i)+'-total']) i=i+1 if subTotal!= float(form.data['total']): form.add_error('total', "Total is incorrect.") return self.render_to_response(self.get_context_data(form=form,item_formset=item_formset )) ,它来自ILogger<T>

ILogger
[Route("api/[controller]")] public class TraderController : Controller { private TraderService _service; private readonly ILogger _logger; public TraderController( Func<IBemfeitoDataContext> context, ILogger<TraderController> logger //<-- note the change here ) { _service = new TraderService(context, logger); _logger = logger; } } 内调用.AddLogging()时,

ILogger<>会映射到Logger<>CreateDefaultBuilder未直接在服务集合中注册。

完成这项工作后,将控制器与实现问题(即ILogger)耦合的当前设计选择引起了一些担忧。

根据当前代码的使用方式进行假设

TraderService

该服务也应该修复为取决于public class TraderService : ITraderService { private readonly ILogger logger; public TraderService(Func<IBemfeitoDataContext> context, ILogger logger) { this.logger = logger; //... } //...code removed for brevity }

ILogger<T>

并且应该重构控制器以依赖于服务抽象而不是实现。

public class TraderService : ITraderService {
    private readonly ILogger logger;

    public TraderService(Func<IBemfeitoDataContext> context, ILogger<TraderService> logger) {
        this.logger = logger;
        //...
    }

    //...code removed for brevity
}

所有涉及的类将在解析时显式注入其依赖项。

此答案假定{DI封容器中已注册[Route("api/[controller]")] public class TraderController : Controller { private readonly ITraderService service; private readonly ILogger logger; public TraderController(ITraderService service, ILogger<TraderController> logger) { this.service = service; this.logger = logger; } //... } ITraderService

答案 1 :(得分:1)

同时注入了 ILoggerFactory 和通用ILogger<T>。这意味着您可以像这样使用控制器:

   [Route("api/[controller]")]
   public class TraderController : Controller {
       private readonly ITraderService service;
       private readonly ILogger logger;
       public TraderController(ITraderService service, ILoggerFactory loggerFactory) 
       { 
           this.service = service;
           this.logger = loggerFactory.CreateLogger<TraderController>();
       }
       //...
   }