アルパカのメモ

設定ファイルをコンソールアプリで使用する

概要

.NET Core のコンソールアプリケーションでも設定ファイルを利用できる。

NuGet パッケージの Microsoft.Extensions.Configuration とその配下のパッケージを使う。 キーと値のペア かつ キーは複数レベルの階層にわたる設定が作れる。 たとえば、SampleApp:Users:Tarouという感じで、階層ごとにコロンで区切って指定する。 設定値はすべてstringで、値をPOCOオブジェクトにバインドする機能もある。 このAPIはASP.NETでは使われてきたが、それ以外のプラットフォームでも使える。

参考:Configuration in ASP.NET Core | Microsoft Docs

前提条件:

  • .NET Core 3.1
  • Visual Studio 2019 で開発

NuGet パッケージの追加

Microsoft.Extensions.Configuration から始まるパッケージ群を、目的に合わせて追加する。

設定ファイルの形態によって、以下のいずれかを追加する。

  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.Ini
  • Microsoft.Extensions.Configuration.Xml
  • その他の Configuration Provider は ドキュメント 参照。

設定値をPOCOオブジェクトへバインドさせたい場合は、以下を追加する。

  • Microsoft.Extensions.Configuration.Binder

例えば、設定ファイルはjsonファイルにしつつ、POCOオブジェクトへのバインドも利用したい場合は、 Microsoft.Extensions.Configuration.JsonMicrosoft.Extensions.Configuration.Binder の2つを追加する。

インメモリを使ったサンプル

コード上に設定値を書く、最もシンプルなもの。

NuGet パッケージは以下2つを追加する。

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Binder
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;

class Program
{
    public static void Main(string[] args = null)
    {
        // コード上で設定値を作る
        var values = new Dictionary<string, string>()
        {
            ["Profile:UserName"] = "太郎",
            ["ConnectionStrings:str1"] = "接続文字列",
            ["AppConfiguration:Model1:param1"] = "400",
            ["AppConfiguration:Model1:param2"] = "600"
        };

        // ビルダーに設定値を渡す
        var builder = new ConfigurationBuilder();
        builder.AddInMemoryCollection(values);

        // Configurationクラスを作る
        IConfiguration config = builder.Build();

        // 設定値を取得する
        Console.WriteLine($"Hello {config["Profile:UserName"]}");

        // 接続文字列は専用の取得メソッドがある
        // 「ConnectionStrings」という階層にある設定値を取得する
        Console.WriteLine(config.GetConnectionString("str1"));

        // POCOオブジェクトにバインド
        var model = new Model1();
        config.GetSection("AppConfiguration:Model1").Bind(model);

        Console.WriteLine(model);
    }
}

下記はバインドに使ったPOCOオブジェクトのサンプル。

class Model1
{
    public string param1 { get; set; }
    public string param2 { get; set; }

    public override string ToString()
    {
        return $"param1={param1}, param2={param2}";
    }
}

下記はサンプルの実行結果。

Hello 太郎
接続文字列
param1=400, param2=600

JSONファイルを使ったサンプル

NuGet パッケージは以下3つを追加する。

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Binder
  • Microsoft.Extensions.Configuration.Json

下記はJSONファイルのサンプル。

{
  "Profile": {
    "UserName": "太郎"
  },
  "ConnectionStrings": {
    "str1": "接続文字列"
  },
  "AppConfiguration": {
    "Model1": {
      "param1": "400",
      "param2": "600"
    }
  }
}

設定ファイルのプロパティの「出力ディレクトリにコピー」を「常にコピーする」または「新しい場合はコピーする」に変更する。

下記はプログラムのサンプル。

using Microsoft.Extensions.Configuration;
using System;

class Program
{
    public static void Main(string[] args = null)
    {
        // ビルダーにJSONファイルを追加
        var builder = new ConfigurationBuilder();
        builder.AddJsonFile("appsettings.json");

        // Configurationクラスを作る
        IConfiguration config = builder.Build();

        // 設定値を取得する
        Console.WriteLine($"Hello {config["Profile:UserName"]}");

        // 接続文字列は専用の取得メソッドがある
        // 「ConnectionStrings」という階層にある設定値を取得する
        Console.WriteLine(config.GetConnectionString("str1"));

        // POCOオブジェクトにバインド
        var model = new Model1();
        config.GetSection("AppConfiguration:Model1").Bind(model);

        Console.WriteLine(model);
    }
}

出力結果はインメモリのサンプルと同じ。

UserSecrets を使う

設定ファイルに、DBやクラウドサービスへの接続文字列など、Git等に保存したくない情報が含まれる場合、 その設定値を一部「ユーザーシークレット」に分けて保存できる。 「ユーザーシークレット」はPCのどこか別の場所に保存される。

参考:ASP.NET Core での開発におけるアプリシークレットの安全な保存 | Microsoft Docs

UserSecrets を編集する

プロジェクトで右クリック → 「ユーザーシークレットの管理」をクリック。

secrets.json ファイルが表示されるので、編集して保存する。

このとき、プロジェクトが ASP.NET Core のものなら難なく secrets.json が開くが、コンソールアプリ等だと Visual Studio が自動的に NuGet パッケージの Microsoft.Extensions.Configuration.UserSecrets を参照に加えようとする。 ただ、追加しようとするバージョンが低いせいか、私の環境では失敗したというダイアログが出た。

その場合は、手作業で同パッケージをインストールしてから、もう一度「ユーザーシークレットの管理」をクリックするところからやり直す。

↑ 手作業で追加したパッケージ (ダイアログではv3.1と書かれていたが、最新版はv5.0だった)

UserSecrets を読み込む

ASP.NET や 汎用ホスト(GenericHost) を使っている場合は、自動的に読み込む。

それ以外の場合は、ConfigurationBuilderAddUserSecrets メソッドを呼び出す。

using Microsoft.Extensions.Configuration;
using System;

class Program
{
    public static void Main(string[] args = null)
    {
        var builder = new ConfigurationBuilder();
        builder.AddJsonFile("appsettings.json");
        builder.AddUserSecrets<Program>();
    }
}

型パラメータには、コンソールアプリのアセンブリに含まれるクラスを指定する。 とりあえずエントリーポイントになる Program にしておけば無難だと思われる。