代码之家  ›  专栏  ›  技术社区  ›  Matthew Flynn

在运行Asp的Webapi 2上使用Serilog创建ILogger。净核心2

  •  2
  • Matthew Flynn  · 技术社区  · 6 年前

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

    我已经添加了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:无法解析类型“Microsoft”的服务。扩展。日志记录。ILogger“正在尝试激活”WebApi。控制器。TraderContactController’。

    我是否需要为 ILogger公司 在启动时。cs。有人能告诉我我在这里错过了什么吗?正如我所设想的那样,因为日志记录构建在核心管道中,所以它知道如何解决这个问题?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Nkosi    6 年前

    您需要重构控制器以期望通用记录器 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;
        }
    }
    

    ILogger<> 已映射到 Logger<> 什么时候 .AddLogging() 在中调用 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
    }
    

    服务还应固定为依赖于 i触发器(&L);T>

    public class TraderService : ITraderService {
        private readonly ILogger logger;
    
        public TraderService(Func<IBemfeitoDataContext> context, ILogger<TraderService> logger) {
            this.logger = logger;
            //...
        }
    
        //...code removed for brevity
    }
    

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

    [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 TraderService公司 在DI容器中注册。

        2
  •  1
  •   Tena    6 年前

    二者都 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>();
           }
           //...
       }