XAMLを使わないWPF入門21「Appクラスの使い方」

コンピュータ

AppクラスはWPFアプリケーション全体の管理を行うためのクラスです。
正直XAMLを使う場合は殆ど触ることがなかったクラスではありますが、XAMLを使わないWPFプログラミングをする場合、利用したい場面が増えてきますので、調べたことをまとめて見ました。

AppコンストラクタとStartup()

アプリの初期化の流れは以下の基本的に順番になります。

アプリケーションのエントリポイント→Appコンストラクタ→OnStartup()

ファイル名:App.cs


using System;
using System.Windows;

public class App : Application
{
    public AppConfig Config { get; private set; }
    public Logger Logger { get; private set; }
    
    // コンストラクタ
    public App()
    {
        // アプリの設定ファイルの読み込み
        var json = File.ReadAllText("appsettings.json");
        // 設定オブジェクトをプロパティとしてセット
        Config = JsonSerializer.Deserialize<AppConfig>(json);
        // 設定オブジェクトのログパスからログオブジェクトの生成
        Logger = new Logger(Config.LogPath);
    }
    
    // エントリポイント
    [STAThread]
    public static void Main(string[] args)
    {
        // Appオブジェクトの生成
        var app = new App();
        // アプリの実行
        app.Run();
    }
    
    // スタートアップメソッド
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        // メインウィンドウの生成
        var win = new MainWindow();
        // メインウィンドウの表示
        win.Show();
    }
}

エントリポイント

主にAppオブジェクトを生成し、app.Run()でアプリを実行します。

Appコンストラクタ

実質アプリ全体の初期化処理を行うことになります。
サンプルコードでは、ログオブジェクトの初期化を行っています。
他に考えられる使い方として、ワーカースレッドの生成などが考えられます。
意外となんでも出来てしまいますが、できる限り次の手順のOnStartup()に任せる用にしたほうが良いと思います。

OnStartup()

AppのStartupイベントで呼出されるメソッド。
サンプルではメインウィンドウオブジェクトの生成と表示を行っています。
メインウィンドウを作成する前に行う準備処理はここで行うことになります。

  • コマンドライン引数など起動オプションの分岐
  • ログイン処理

Appオブジェクトの参照

アプリ全体で利用する設定情報を管理する関係上、アプリのどこからでもアクセスする必要があります。

その真場合以下のようなコードでオブジェクトを呼び出せます。

var app = (App)Application.Current;

Appクラスに明示的にキャストする必要があります。

アプリ終了処理

アプリの終了処理はAppクラスのOnExit()メソッドで記述すると良いです。

サンプルコード

protected override void OnExit(ExitEventArgs e)
{
    // ワーカーの終了
    _cts.Cancel();

    try
    {
        _workerTask.Wait(); // 終了を待つ
    }
    catch (AggregateException) { }

    base.OnExit(e);
}

  • ワーカースレッドの終了処理
  • アプリの管理情報の保存

MainWindowのクローズ系のイベントなどに記述しがちな処理ですが、AppのOnExit()で処理したほうが良さそうです。

まとめ

アプリ全体で利用する可能性のあるデータは、Appクラスで管理すると良さそうです。
そうすることで、肥大化しやすいMainWindowと役割の一部をAppクラスに移管することが出来ると思います。

コメント