C#依赖注入使用疑问:跨类调用方法及日志输出顺序问题
问题解答
一、Test类调用Application.TestRun的正确实现
你的修改方向是对的,通过构造函数注入IApplication依赖是.NET依赖注入的标准做法,这里可以做一点小优化:把_app字段改为readonly,确保它不会被意外修改:
namespace DependencyInjectionDemo.Services { internal interface ITest { void CallTestRun(); } internal class Test : ITest { private readonly IApplication _app; // 改为readonly public Test(IApplication app) { _app = app; } public void CallTestRun() { Console.WriteLine("Hello, World form the Test class!"); _app.TestRun(); } } }
同时在Program.cs中注册ITest和Test的映射,你已经完成的这一步是正确的:
services.AddSingleton<ITest, Test>();
二、日志输出顺序不符合预期的原因及解决办法
问题原因
默认情况下,.NET的Console日志提供程序采用异步缓冲输出,而Console.WriteLine是同步直接输出的。这就导致:当你先调用Console.WriteLine,再调用_logger.LogInformation时,日志信息可能因为缓冲延迟,反而在Console.WriteLine的内容之后才输出,出现顺序混乱。
比如代码执行顺序是:
Console.WriteLine("Hello, World form the Test class!");→ 同步输出到控制台_app.TestRun()里先执行_logger.LogInformation(...)→ 异步写入缓冲- 再执行
Console.WriteLine("Hello, World form the Application class!");→ 同步输出
但实际输出可能出现日志信息滞后于Console输出的情况。
解决办法
有两种方式可以解决这个问题:
方法1:禁用Console日志的异步缓冲
在构建Host的时候,配置Console日志提供程序禁用异步:
IHost _host = Host.CreateDefaultBuilder() .ConfigureLogging(logging => { logging.ClearProviders(); logging.AddConsole(options => { options.DisableColors = false; options.UseUtcTimestamp = false; options.Async = false; // 禁用异步缓冲 }); }) .ConfigureServices(services => { services.AddSingleton<IApplication, Application>(); services.AddSingleton<ITest, Test>(); }) .Build();
方法2:统一使用ILogger输出,避免混合Console.WriteLine和日志
把所有Console.WriteLine替换为ILogger.LogInformation,这样所有输出都走同一个日志管道,顺序就会保持一致:
修改Application.cs:
public void TestRun() { _logger.LogInformation("Logging form the Application classssssssssssss!"); _logger.LogInformation("Hello, World form the Application class!"); }
修改Test.cs:
internal class Test : ITest { private readonly IApplication _app; private readonly ILogger<Test> _logger; // 注入ILogger public Test(IApplication app, ILogger<Test> logger) { _app = app; _logger = logger; } public void CallTestRun() { _logger.LogInformation("Hello, World form the Test class!"); _app.TestRun(); } }
这样所有输出都会严格按照代码执行顺序输出,不会出现顺序混乱。
内容的提问来源于stack exchange,提问作者BTOM
相关产品推荐
相关产品推荐

