【问题标题】:.NET Core DI and sub classes.NET Core DI 和子类
【发布时间】:2021-03-04 02:38:28
【问题描述】:

这里是 .NET Core 的新手。我搜索了另一个文档、线程或指南来回答我的问题,但找不到,如果您认为有,请指出。

我正在尝试使用 DI 创建一个简单的 .NET 5 控制台应用程序,但实际上卡在了使用日志记录构建类上。

  1. 这是在 .NET Core 中使用 DI 将记录器(或任何其他服务)传递给子类的正确方法吗? 根据下面的代码,在我的父类构造函数中,我为每个子类使用一个额外的 ILogger,例如。 ILogger<SubClass>?

    public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)
    
  2. 如何在我的静态进程StaticProc 中初始化记录器?

    public static async Task<bool> StaticProc()
    

程序.cs:

使用 Microsoft.Extensions.Configuration; 使用 Microsoft.Extensions.DependencyInjection; 使用 Microsoft.Extensions.Hosting; 使用 Microsoft.Extensions.Logging; 使用系统; 使用 System.IO; 使用 System.Threading.Tasks; 命名空间 ConsoleApp1 { 课堂节目 { 静态异步任务 Main(string[] args) { var builder = new ConfigurationBuilder(); 构建配置(构建器); var host = Host.CreateDefaultBuilder() .ConfigureServices((上下文,服务)=> { services.AddTransient(); services.AddTransient(); }) .ConfigureLogging(logBu​​ilder => { logBu​​ilder.SetMinimumLevel(LogLevel.Trace); logBu​​ilder.AddLog4Net("log4net.config"); }) 。建造(); var log = host.Services.GetService().CreateLogger(); log.LogInformation($"应用程序启动"); var svc = ActivatorUtilities.CreateInstance(host.Services); 等待 svc.Run(); log.LogInformation($"应用程序结束"); } 静态无效 BuildConfig(IConfigurationBuilder 构建器) { builder.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", 可选:false, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"}.json", optional: true) .AddEnvironmentVariables(); } } }

TestClass.cs:

使用 Microsoft.Extensions.Configuration; 使用 Microsoft.Extensions.Logging; 使用 System.Threading.Tasks; 命名空间 ConsoleApp1 { 公共类 TestClass : ITestClass { 私有只读 ILogger _log; 私有只读 ILogger _subClassLog; 私有只读 IConfiguration _config; 公共测试类(ILogger 日志,ILogger subClassLog,IConfiguration 配置) { _log = 日志; _subClassLog = subClassLog; _config = 配置; } 公共异步任务运行() { for (int i = 0; i ("循环"); i++) _log.LogDebug("循环调试 {loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogInformation("循环信息 {loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogWarning("循环警告 {loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogError("循环错误{loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogCritical("循环临界 {loopNumber}", i); var subClass = new SubClass(_subClassLog, _config); 等待 subClass.AnotherProc(); 等待子类.StaticProc(); } } }

子类.cs:

使用 Microsoft.Extensions.Configuration; 使用 Microsoft.Extensions.Logging; 使用系统; 使用 System.Threading.Tasks; 命名空间 ConsoleApp1 { 公共类子类:ISubClass { 私有只读 ILogger _log; 私有只读 IConfiguration _config; 公共子类(ILogger 日志,IConfiguration 配置) { _log = 日志; _config = 配置; } 公共异步任务 AnotherProc() { for (int i = 0; i ("循环"); i++) _log.LogDebug("循环调试 {loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogInformation("循环信息 {loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogWarning("循环警告 {loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogError("循环错误{loopNumber}", i); for (int i = 0; i ("循环"); i++) _log.LogCritical("循环临界 {loopNumber}", i); } 公共静态异步任务 StaticProc() { var returnBool = true; 尝试 { 抛出新异常(“”); } 捕捉(例外前) { 返回布尔=假; // 没有实例,所以没有 _log 异常。 // 如何创建独立的 ILogger? } 返回返回布尔; } } }

appsettings.json:

{ “循环”:15 }

log4net.config:

布局> 布局>

【问题讨论】:

标签: c# .net-core dependency-injection log4net asp.net-core-5.0


【解决方案1】:

总结

您也可以注入ILoggerFactory 而不是ILogger

public TestClass(ILoggerFactory loggerFactory, IConfiguration config)
{
     // create a class logger
     _log = loggerFactory.CreateLogger<TestClass>();

     // and whenever you need a new instance of a special class logger use this:
     _subClassLog = loggerFactory.Create<SubTestClass>();
     _config = config;
}

但请注意,这会创建 ILogger 的新实例。 Logging in asp net core 在您的情况下,如果您确实需要带有记录器的静态方法,则仅在它已经存在时才创建它:

private static readonly ILogger<SubClass> _log;
private readonly IConfiguration _config;

public SubClass(ILoggerFactory loggerFactory, IConfiguration config)
{
     _log = _log ??= loggerFactory.CreateLogger<SubClass>();
     _config = config;
}

但我会更喜欢或更好地建议您在没有静态的情况下执行此操作,只需将服务注册为单例。

示例 1

我在这里添加了一个完整的例子:dotnet fiddle Example 1 还可以使用 cmets 中提到的控制台应用程序的工作 DI。

示例 2

Imo 你不应该将它与静态方法一起使用。看看我的第二个例子dotnet fiddle Example 2

【讨论】:

  • 这是用于asp.net / web api的,他要求控制台应用程序,据我了解,该应用程序没有可用的DI服务。
  • @VilsadPP 刚刚用示例更新了我的答案,还使用了一个有效的 ConsoleApp DependencyInjection。
  • 感谢@Martin,这太棒了。我还用您的示例更改了初始化容器的方式。
猜你喜欢
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2021-04-14
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
相关资源
最近更新 更多