サーバのエンドポイントとストレージのファイルパスは派生クラスで変更する

投稿者: | 2021年6月12日

 サーバのエンドポイントとストレージのファイルパスのプロパティはvirtual修飾子で基底クラスを作って、後で派生クラスで変更できる設計にします。そのメリットとサンプルコードによる実装例を解説。

サーバのエンドポイントとストレージのファイルパスを変更できる設計にするメリット

サーバのエンドポイントを変更できる設計にするメリットは、開発環境で本番サーバにアクセスしないでステージングサーバかモックサーバといった開発用のサーバで開発するためです。
 詳しい説明は”—この記事—”で解説しています。

ストレージのファイルパスを変更できる設計にメリットは、テストを作成できる設計にするためです。
 例えば、ファイルパスがアプリケーションフォルダやドキュメントフォルダといったユーザーからアクセスできるパスを指定する仕様の場合、この値のままテストプロジェクトで使ってしまうと、そのフォルダにあるファイルを変更したことによりテスト結果が変わってしまう懸念があります。そのため、ファイルパスのルートフォルダはすべてアセンブリフォルダに変更できる設計にします。

サンプルコード

サーバのエンドポイントとストレージのファイルパスの設計例を記述します。

サーバのエンドポイント

下記はサーバのエンドポイントのプロパティをvirtual修飾子で作成した基底クラスです。基底クラスは本番サーバの値で作成します。(IHttpUrlインターフェースはProductUrlのプロパティと同じなためコードの記載は省略)

    public class ProductUrl : IHttpUrl
    {
        public virtual string SaverDomain => $"http://task.nakashima.toshiki.jp";

        public string SessionEndPoint => "credential/verfication";

        public virtual string TaskEndPoint => "{user_id}/task";

        public string LogEndPoint => "{user_id}/log";

        public string ConfigEndPoint => "{user_id}/config";
    }

下記は基底クラスからエンドポイントをステージングサーバに変更した派生クラスです。

public class StagingUrl : ProductUrl
{
    public override string SaverDomain => $"http://staging.task.nakashima.toshiki.jp";
}

この方法であれば派生クラスを作成するだけで、いくらでもエンドポイントを拡張できますので、同じようにモックサーバのエンドポイントも簡単に作成できます。

補足ですがカッコ({})で囲まれたHttpセグメント文字はRestSharpライブラリのメソッドを使って置き換えます。組込のHttpClientクラスを使う場合はカッコ内の文字を数字にして文字列リテラルで置き換えると良いと思います。

ストレージのファイルパス

下記はストレージのファイルパスのプロパティをvirtual修飾子で作成した基底クラスです。

    public class FileInfoFacade : IFileInfoFacade
    {
        public virtual string InstalledLocation => Environment.CurrentDirectory;

        public virtual string ApplicationLocation => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "TaskNote");

        public virtual string Database => "database.db";

        public virtual string AppSetting => "appsettings.json";

        public virtual DirectoryInfo GetTraceLogDirectoryInfo() => new DirectoryInfo(Path.Combine(ApplicationLocation, TraceLogFolder));

        public virtual FileInfo GetDatabaseFileInfo() => new FileInfo(Path.Combine(ApplicationLocation, Database));

        public virtual FileInfo GetAppSettingFileInfo() => new FileInfo(Path.Combine(InstalledLocation, AppSetting));
    }

上記のコードから派生クラスを作成して、アプリケーションフォルダをアセンブリフォルダに変更します。また、並行処理しても結果が変わらないようにTestOptionsでプロパティを持たせてテストによってファイルの参照先を変更できる設計にします。下記サンプルコードはデータベースの名前を変更できるようにして各テストが別々のデータベースを参照する設計にしています。

public class TestFileInfoFacade : FileInfoFacade
{
    private readonly TestOptions _options;

    public TestFileInfoFacade(TestOptions options)
    {
        _options = options ?? throw new ArgumentNullException(nameof(options));
    }

    public override string InstalledLocation => Environment.CurrentDirectory;

    // アプリケーションフォルダをアセンブリフォルダに変更
    public override string ApplicationLocation => Path.Combine(Environment.CurrentDirectory, "Application");

    public override string Database => $"{_options.Name}.db";

    public override string NLog => "NLog.test.config";

    public override string AppSetting => "appsettings.test.json";

    public override FileInfo GetDatabaseFileInfo() => new FileInfo(Path.Combine(Environment.CurrentDirectory, "Database", Database));

}

public class TestOptions
{
    public TestOptions(string name)
    {
        Name = name ?? throw new System.ArgumentNullException(nameof(name));
    }

    public string Name { get; }
}

保存パスを動的に変えたい場合は「Root/{0}/{1}/fileName.abc」と記載して後でC#の文字リテラルで置き換えられる設計にすると良いと思います。サーバのエンドポイントもRestSharpライブラリを使わないなら同様の方法で変更できる設計になると思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)