WPFアプリケーションの初期化処理でアプリケーションでSQLiteを使うとして、データベースファイルを設定ファイルから読み込むようにしたい。
データベースファイルのパスは基本的に変更されることは無いので定数(const)で定義したいところですが、設定ファイルから読み込む場合constで定義することは出来ません。ドメイン駆動設計(DDD)のValue Objectというクラスが、初期化時に設定した値が破棄まで不変である性質があるとのことなので、試してみたいと思います。
サンプルコード
ファイル名:ValueObject
namespace MwFileManager.Domain.ValueObjects;
public abstract class ValueObject<T> where T : ValueObject<T>
{
public override bool Equals(object? obj)
{
var vo = obj as T;
if (vo == null)
{
return false;
}
return EqualsCore(vo);
}
public static bool operator ==(ValueObject<T>? vo1, ValueObject<T>? vo2)
{
return Equals(vo1, vo2);
}
public static bool operator !=(ValueObject<T>? vo1, ValueObject<T>? vo2)
{
return !Equals(vo1, vo2);
}
public abstract override int GetHashCode();
protected abstract bool EqualsCore(T other);
}
ValueObjectの特徴として、内部に保持する値が変更不可(生成から破棄まで不変)、値が同じであれば異なるインスタンスでも同じと判定されます。
ファイル名:DbFilePathObject.cs
namespace MwFileManager.Domain.ValueObjects;
public class DbFilePathObject: ValueObject<DbFilePathObject>
{
public DbFilePathObject(string dbFilePath)
{
Value = dbFilePath;
}
public static implicit operator DbFilePathObject(string dbFilePath)
{
return new DbFilePathObject(dbFilePath);
}
public string Value { get; } = "";
public override int GetHashCode() => Value.GetHashCode();
protected override bool EqualsCore(DbFilePathObject other)
{
return Value == other.Value;
}
public override string ToString()
{
return Value.ToString();
}
}
ValueObjectを継承しDbFilePathObjectとしてデータベースのファイルを扱うクラスとして実装します。
コンストラクタでValueをセットしていますが、プロパティとしてget;のみ定義してるので、変更することは出来ません。
ファイル名:SettingHelper
using MwFileManager.Domain.ValueObjects;
namespace AppStartup01;
public static class SettingHelper
{
public static DbFilePathObject? DbFilePath;
}
設定関係をまとめたclassになります。プロジェクトのどこからでも参照可能。
ファイル名:App.xaml.cs
using System.Windows;
using System.Diagnostics;
using System.IO;
namespace AppStartup01;
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
// 設定ファイルのパス
const string CONFIG_FILE_PATH = @".\config.txt";
// デフォルトのデータベースファイルのパス
const string DEFAULT_DB_PATH = @".\sqlite.db";
protected override void OnStartup(StartupEventArgs e)
{
Debug.Print("App.OnStartup()");
if (File.Exists(CONFIG_FILE_PATH))
{
using (var stream = new StreamReader(CONFIG_FILE_PATH))
{
SettingHelper.DbFilePath = stream.ReadLine() ?? DEFAULT_DB_PATH;
}
} else {
SettingHelper.DbFilePath = DEFAULT_DB_PATH;
}
}
}
OnStartup()はアプリケーション開始時に呼び出されるので、こちらに初期化コードを記述してみました。
テキストファイルを読み込んでSettingHelper.DbFilePathにセットしています。
ファイル名:MainWindow.xaml.cs
using System.Windows;
using System.Diagnostics;
namespace AppStartup01;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
Debug.Print($"MainWindow() {SettingHelper.DbFilePath}");
InitializeComponent();
}
}
設定されたSettingHelper.DbFilePathが参照できることを確認するコードに成ります。
思った通りに動作はしましたので、実験としては成功なのですが、今回のケースはValue Objectの代わりにreadonly stringの方がコード量が少なくて良さそうな感じがします。
コメント