前書き
Windows Forms版を書いたので、WPF版もついでに。
実装環境
OS: Windows 11(25H2)
Visual Studio: Professional 2022(Version 17.14.33)
C#ターゲットフレームワーク: .NET 9.0
NLog: 6.1.1
実装コード
Windows Formsの時と同様に、NuGetで、Microsoft.Extensions.DependencyInjection・Microsoft.Extensions.Hosting・NLog本体・NLog.Extensions.Loggingを追加している。
汎用ホストやDIが不要ならNLog本体だけあればいいはず。
App.xaml.cs全体
App.xaml.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using NLog.Targets;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public IHost MyHost { get; }
public App()
{
MyHost = Host.CreateDefaultBuilder()
.ConfigureLogging((context, logging) =>
{
logging.ClearProviders();
logging.AddNLog(LogSetting(true));
})
.ConfigureServices((context, services) =>
{
services.AddSingleton<MainWindow>();
})
.Build();
}
/// <summary>
/// MainWindowでコンストラクタ―インジェクションを使用している場合
/// xamlのStartupUriで起動しようとすると例外が発生してしまう問題の回避策
/// </summary>
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow = MyHost.Services.GetRequiredService<MainWindow>();
MainWindow.Show();
}
/// <summary>
/// NLogの設定
/// </summary>
/// <param name="fileOutput">true: ファイルへも出力する</param>
/// <returns></returns>
private static NLog.Config.LoggingConfiguration LogSetting(bool fileOutput = false)
{
var config = new NLog.Config.LoggingConfiguration();
// Visual Studioのデバッグへの出力
var logDebug = new NLog.Targets.DebuggerTarget("logDebug")
{
Layout = "${longdate} [${uppercase:${level}}] ${message}${exception:format=Message, Type, ToString:separator=\r\n}",
};
#if DEBUG
config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logDebug);
#else
config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, logDebug);
#endif
if (fileOutput)
{
var logfile = new FileTarget("logfile") // ファイルへの出力
{
FileName = "${basedir}/logs/${shortdate}.log",
Layout = "${longdate} [${uppercase:${level}}] ${message}${exception:format=Message, Type, ToString:separator=\r\n}",
MaxArchiveFiles = 10, // アーカイブ世代数
};
#if DEBUG
config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logfile);
#else
config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, logfile);
#endif
}
return config;
}
}
}
LogSettingメソッド内にNLogの設定をまとめている。
メソッド内はWindows Formsの時と同じ内容。
App.xamlの修正
App.xaml.csのコメントにも記載したように、MainWindowでコンストラクタ―インジェクションを使用する場合、起動時に例外が発生してしまうので対処が必要。
App.xaml
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:WpfApp1"
- StartupUri="MainWindow.xaml">
+ xmlns:local="clr-namespace:WpfApp1">
<Application.Resources>
</Application.Resources>
</Application>
xaml内でのStartupUriを削除して、App.xaml.cs内のOnStartupでMainWindowを表示させるように変更した。
MainWindow.xaml.cs全体
MainWindow.xaml.cs
using Microsoft.Extensions.Logging;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow(ILogger<MainWindow> logger)
{
InitializeComponent();
_logger = logger;
_logger.LogDebug("Launch Application");
}
private ILogger<MainWindow> _logger;
}
}
コンストラクタ―インジェクションでILoggerを受け取るように変更している。