はじめに
この記事では以下の内容を紹介します。
- WPF で SimpleInjector を使用する方法
- WPF と SimpleInjector を使用している状態で、ZLogger を使用する方法
それぞれの基本的な説明などは省いていますので、必要に応じて公式ドキュメントなどもご確認ください。
実行環境
- Windows 11
- .Net 8
- SimpleInjector:5.5.0
- ZLogger:2.5.10
WPF プロジェクトテンプレートでプロジェクトを作成し、それぞれ NuGet から最新版をインストールしました。
SimpleInjector を設定する
まず、デフォルトで入っているMainWindow.xaml
の以下の記述を削除します。
これを消さないと、後で 2 個の Window が起動してしまいます。
StartupUri="MainWindow.xaml"
あとはApp.xaml.cs
に以下の記述を追加します。
/// <summary>
/// アプリのメインエントリーポイント
/// </summary>
public partial class App : Application
{
/// <summary>
/// DIコンテナ
/// </summary>
public static Container? Container { get; private set; }
/// <summary>
/// サービス登録
/// </summary>
/// <param name="container">DIコンテナ</param>
private static void ConfigureContainer(Container container)
{
container.Register<MainWindow>(Lifestyle.Singleton);
}
/// <inheritdoc/>
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// SimpleInjectorのコンテナを作成
Container = new Container();
// サービス登録
ConfigureContainer(Container);
// コンテナを検証
Container.Verify();
// メインウィンドウの表示
var mainWindow = Container.GetInstance<MainWindow>();
mainWindow.Show();
}
/// <inheritdoc/>
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
Container?.Dispose();
}
}
コンテナをしっかりアプリ終了時に Dispose します!
ZLogger を設定して SimpleInjector に登録する
RegisterLogger
というロガーの登録メソッドを App クラス内に用意し、以下のようにConfigureContainer
メソッド内で呼び出すようにしました。
/// <summary>
/// サービス登録
/// </summary>
/// <param name="container">DIコンテナ</param>
private static void ConfigureContainer(Container container)
{
container.Register<MainWindow>(Lifestyle.Singleton);
RegisterLogger(container);
}
RegisterLogger
は以下のようになっています。
AddZLoggerFile
はlog/log.txt
というパスにログを書き込みます。
AddZLoggerInMemory
はDebug.WriteLine
で VisualStudio の出力タブにログが表示されるようにする設定です。
また、どちらもUsePlainTextFormatter(PlanTextFormatter)
の部分で、ログテキストに日付や時間などの情報を追加しています。
SetPrefixFormatter
は第一引数に、第二引数の値が順番に入ってきます。
{1:short}
の部分にはinfo.LogLevel
が入ってきて、short
とすることで LogLevel を 3 文字にそろえてくれます。
ZLogger>Formatter Configurations
/// <summary>
/// ロガーの登録
/// </summary>
private static void RegisterLogger(Container container)
{
var loggerFactory = LoggerFactory.Create(builder =>
{
_ = builder.ClearProviders();
_ = builder.SetMinimumLevel(LogLevel.Trace);
_ = builder.AddZLoggerFile(
"log/log.txt",
options => options.UsePlainTextFormatter(PlanTextFormatter));
_ = builder.AddZLoggerInMemory(
(options, provider) => options.UsePlainTextFormatter(PlanTextFormatter),
processor => processor.MessageReceived += log => Debug.WriteLine(log));
});
container.RegisterInstance(loggerFactory);
container.Register(typeof(ILogger<>), typeof(Logger<>), Lifestyle.Singleton);
// テキストフォーマッタの設定ローカルメソッド
static void PlanTextFormatter(PlainTextZLoggerFormatter formatter)
{
formatter.SetPrefixFormatter($"{0:yy-MM-dd-HH:mm:ss.ff}|{1:short}|", (in MessageTemplate template, in LogInfo info) => template.Format(info.Timestamp.Local, info.LogLevel));
formatter.SetSuffixFormatter($" ({0})", (in MessageTemplate template, in LogInfo info) => template.Format(info.Category));
formatter.SetExceptionFormatter((writer, ex) => Utf8StringInterpolation.Utf8String.Format(writer, $"{ex.Message}"));
}
}
これで SimpleInjector を使いつつ、あとは別の受取クラスでコンストラクタでILogger<Hoge> logger
と書けば指定の Logger を得られるようになりました!