.NET CoreDIおよびサブクラス
Nov 21 2020
ここで.NETCoreの新機能。私の質問に答える別のドキュメント、スレッド、またはガイドを検索しましたが、見つかりません。そうだと思われる場合は、指摘してください。
DIを使用して単純な.NET5コンソールアプリを作成しようとしていますが、文字通り、ロギングを使用したクラスの構造化に行き詰まっています。
これは、.NET CoreのDIを使用してロガー(またはその他のサービス)をサブクラスに渡す正しい方法ですか?以下のコードのように、私の親クラスコンストラクターでは、サブクラスごとに追加のILoggerを使用します。
ILogger<SubClass>
?public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)
静的プロシージャでロガーを初期化するにはどうすればよい
StaticProc
ですか?public static async Task<bool> StaticProc()
Program.cs:
Microsoft.Extensions.Configurationを使用します。 Microsoft.Extensions.DependencyInjectionを使用する; Microsoft.Extensions.Hostingを使用する; Microsoft.Extensions.Loggingを使用する; システムを使用する; System.IOを使用する; System.Threading.Tasksを使用する; 名前空間ConsoleApp1 {{ クラスプログラム {{ static async Task Main(string [] args) {{ var builder = new ConfigurationBuilder(); BuildConfig(ビルダー); var host = Host.CreateDefaultBuilder() .ConfigureServices((context、services)=> {{ services.AddTransient <ITestClass、TestClass>(); services.AddTransient <ISubClass、SubClass>(); }) .ConfigureLogging(logBuilder => {{ logBuilder.SetMinimumLevel(LogLevel.Trace); logBuilder.AddLog4Net( "log4net.config"); }) .Build(); var log = host.Services.GetService <ILoggerFactory>()。CreateLogger <Program>(); log.LogInformation($"Application Started"); var svc = ActivatorUtilities.CreateInstance<TestClass>(host.Services); await svc.Run(); log.LogInformation($"アプリケーションが終了しました"); } static void BuildConfig(IConfigurationBuilderビルダー) {{ builder.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile( "appsettings.json"、オプション:false、reloadOnChange:true) .AddJsonFile($ "appsettings。{Environment.GetEnvironmentVariable(" ASPNETCORE_ENVIRONMENT ")??" Development "}。json"、オプション:true) .AddEnvironmentVariables(); } } }
TestClass.cs:
Microsoft.Extensions.Configurationを使用します。 Microsoft.Extensions.Loggingを使用する; System.Threading.Tasksを使用する; 名前空間ConsoleApp1 {{ パブリッククラスTestClass:ITestClass {{ プライベート読み取り専用ILogger <TestClass> _log; プライベート読み取り専用ILogger <SubClass> _subClassLog; プライベート読み取り専用IConfiguration_config; public TestClass(ILogger <TestClass>ログ、ILogger <SubClass> subClassLog、IConfiguration config) {{ _log =ログ; _subClassLog = subClassLog; _config = config; } public async Task Run() {{ for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogDebug( "Loop debug {loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogInformation( "Loop info {loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogWarning( "Loop warn {loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogError( "ループエラー{loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogCritical( "ループクリティカル{loopNumber}"、i); var subClass = new SubClass(_subClassLog、_config); subClass.AnotherProc();を待つ SubClass.StaticProc();を待つ } } }
SubClass.cs:
Microsoft.Extensions.Configurationを使用します。 Microsoft.Extensions.Loggingを使用する; システムを使用する; System.Threading.Tasksを使用する; 名前空間ConsoleApp1 {{ パブリッククラスサブクラス:ISubClass {{ プライベート読み取り専用ILogger <SubClass> _log; プライベート読み取り専用IConfiguration_config; public SubClass(ILogger <SubClass> log、IConfiguration config) {{ _log =ログ; _config = config; } public async Task AnotherProc() {{ for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogDebug( "Loop debug {loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogInformation( "Loop info {loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogWarning( "Loop warn {loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogError( "ループエラー{loopNumber}"、i); for(int i = 0; i <_config.GetValue <int>( "Loop"); i ++) _log.LogCritical( "ループクリティカル{loopNumber}"、i); } public static async Task <bool> StaticProc() {{ var returnBool = true; 試してみてください {{ 新しいException( "");をスローします。 } キャッチ(例外例) {{ returnBool = false; //インスタンスがないため、_log例外はありません。 //スタンドアロンのILoggerを作成するにはどうすればよいですか? } return returnBool; } } }
appsettings.json:
{{ 「ループ」:15 }
log4net.config:
<?xml version = "1.0" encoding = "utf-8"?> <log4net> <appender name = "Info" type = "log4net.Appender.RollingFileAppender"> <threshold value = "DEBUG" /> <param name = "File" value = "App_Data \\ Log \\ Info.log" /> <param name = "AppendToFile" value = "true" /> <maximumFileSize value = "5120KB" /> <lockingModel type = "log4net.Appender.FileAppender + MinimalLock" /> <maxSizeRollBackups value = "1000" /> <layout type = "log4net.Layout.PatternLayout"> <conversionPattern value = "%d {yyyy-MM-dd HH:mm:ss}-[%t]%-5p%c%x-%m%n" /> </レイアウト> </ appender> <appender name = "Error" type = "log4net.Appender.RollingFileAppender"> <threshold value = "Error" /> <param name = "File" value = "App_Data \\ Log \\ Error.log" /> <param name = "AppendToFile" value = "true" /> <maximumFileSize value = "5120KB" /> <lockingModel type = "log4net.Appender.FileAppender + MinimalLock" /> <maxSizeRollBackups value = "1000" /> <layout type = "log4net.Layout.PatternLayout"> <conversionPattern value = "%d {yyyy-MM-dd HH:mm:ss}-[%t]%-5p%c%x-%m%n" /> </レイアウト> </ appender> <ルート> <appender-ref ref = "Info" /> <appender-ref ref = "Error" /> </ root> </ log4net>
回答
Martin Nov 21 2020 at 00:13
概要
:の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の新しいインスタンスが作成されることに注意してください。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
ここに完全な例を追加しました。dotnetfiddle例1コメントに記載されているようなコンソールアプリのDIも機能します。
例2
Imo静的メソッドでは使用しないでください。ここで私の2番目の例を見てくださいdotnetfiddle例2