如何为 .NET 库配置具有依赖注入的日志记录提供程序

问题描述 投票:0回答:1

我有一个典型的场景,我正在开发 .NET Core 库,并希望调用应用程序能够选择配置日志记录选项。

理想情况下,我想对库中每个类的

ILogger
属性使用依赖注入。我无法解决的是如何让 DI 容器在一个程序集(应用程序可执行文件)中初始化,并在另一个程序集(库程序集)中使用它。

我能想到的最好的例子是下面的示例,其中 DI 容器在执行程序集中初始化,然后存储在库随后访问的“中间”程序集中。我的问题是,是否有一种方法可以不需要 intermediary 程序集,并避免使用可能需要或可能不需要的日志记录实例污染库构造函数? 在下面的设计示例中,每个命名空间代表一个单独的程序集。库程序集对应用程序程序集一无所知。

using System; using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Serilog; namespace MainAssembly { class Program { public static Microsoft.Extensions.Logging.ILogger logger = NullLogger.Instance; static void Main() { Console.WriteLine("DI + Log Test"); // Set up logging factory. var loggerFactory = new LoggerFactory(); var serilogConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss.fff} [{Level}] ({SourceContext}.{Method}) {Message}{NewLine}{Exception}") .CreateLogger(); loggerFactory.AddSerilog(serilogConfig); // Set up dependency injection services. ServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton<LoggerFactory>(loggerFactory); IntermediaryAssembly.DI.ServicesSingleton = serviceCollection.BuildServiceProvider(); // Attempt to get a logger from the DI container. logger = IntermediaryAssembly.DI.TryGetLogger<Program>(); logger.LogDebug("Logging initialised."); var lib = new LibraryAssembly.DoIt(); lib.DoWork(); Console.WriteLine("Finished."); } } } namespace IntermediaryAssembly { public class DI { public static ServiceProvider ServicesSingleton; public static ILogger<T> TryGetLogger<T>() { if (ServicesSingleton != null && ServicesSingleton.GetServices<LoggerFactory>().Any()) { return ServicesSingleton.GetRequiredService<LoggerFactory>().CreateLogger<T>(); } else { return NullLogger<T>.Instance; } } } } namespace LibraryAssembly { public class DoIt { public Microsoft.Extensions.Logging.ILogger logger = NullLogger.Instance; public DoIt() { // Attempt to get a logger from the DI container. logger = IntermediaryAssembly.DI.TryGetLogger<DoIt>(); } public void DoWork() { logger.LogDebug("Doing work..."); } } }

使用的套件:

<ItemGroup> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.1" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" /> <PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> </ItemGroup>


c# logging .net-core dependency-injection
1个回答
0
投票

services.AddLogging();

在您要注入的类中,只需执行基本的构造函数注入,在托管类中输入 ILogger:

private readonly ILogger<DoIt> _logger; public DoIt(ILogger<DoIt> logger) { _logger = logger; }

© www.soinside.com 2019 - 2024. All rights reserved.