2022版を作った後で ConsoleAppFramework https://github.com/Cysharp/ConsoleAppFramework を見つけたので記録。
パッケージ
<PackageReference Include="ConsoleAppFramework" Version="4.0.6" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
設定ファイル
appsettings.json
{
"Id": "101",
"Name": "name1"
}
nlog.config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Error"
internalLogFile="${basedir}\logs\internal-nlog.log">
<extensions>
</extensions>
<variable name="logDirectory" value="${basedir}\logs" />
<targets>
<target xsi:type="File" name="file" fileName="${logDirectory}/log-${shortdate}.log"
layout="${longdate} [${level:uppercase=true}] [${threadid}] ${callsite:includeNamespace=false}#${callsite-linenumber} ${message} ${exception:format=tostring}" />
<target name="Console" xsi:type="console" layout="${longdate} [${level:uppercase=true}] [${threadid}] ${callsite}#${callsite-linenumber} ${message} ${exception:format=tostring}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="file,console" />
</rules>
</nlog>
いずれも "常にコピーする" または "新しい場合はコピーする"を設定しておく
設定クラス
class SampleSettings
{
public int Id { get; set; }
public string Name { get; set; } = "";
}
string はnullable警告が出るので回避のため空文字列で初期化しておくとか、nullableにしておくとか、 nullable referenceを使わないとかしておく。
コマンドクラス
コマンドの本体
class Foo : ConsoleAppBase
{
private readonly Microsoft.Extensions.Logging.ILogger _logger;
private readonly SampleSettings _settings;
public Foo(IOptions<SampleSettings> settings, ILogger<Foo> logger)
{
_settings = settings.Value;
_logger = logger;
}
public void Hello(string name)
{
_logger.LogTrace($"{_settings.Id} {_settings.Name}");
_logger.LogTrace($"{name}");
}
}
ConsoleAppFramework が Microsoft.Extentions.DependencyInjection をサポートしているおかげで対象Commandへの注入が効く。
ここではIOption と ILogger を注入しているけど、EFCore6とか使うならDbContext も注入できるだろうしほかの関連サービスも行けるはず。
プログラム本体
今回は VS2022/c#10 なので void Main(string[] args
不要
var builder = ConsoleApp.CreateBuilder(args);
builder.ConfigureServices((ctx, services) =>
{
// Register appconfig.json to IOption<MyConfig>
services.Configure<SampleSettings>(ctx.Configuration);
// Using Cysharp/ZLogger for logging to file
services.AddLogging(logging =>
{
logging.ClearProviders();
logging.AddNLog();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
});
});
var app = builder.Build();
app.AddCommands<Foo>();
app.Run();
ConfigureServices 内でサービス設定やらログ設定やらを実行しておく。
その他
前回よりはコード記述量が大幅に減る。よい。