C#入門編です。今回はC#におけるモダンな設定管理の方法について解説します。

API の URL やアプリの動作モードなど、環境によって変えたい値をコードに直接書いていませんか?

本記事は以下の方に役立つ内容となっています。

  • 設定をコードの外に出す理由を理解したい初心者の方
  • appsettings.jsonの基本的な使い方を学びたい方
  • IConfigurationで設定を読み取る方法を知りたい方

これまでC#入門編では、C#の基本文法、オブジェクト指向、コレクション・LINQや非同期処理、標準ライブラリ(文字列・ファイル操作)などについて扱ってきました。

ここからは、次のようなモダンなC#の実務アプリの基盤になっている内容について解説をしていきます。

  • 設定管理:appsettings.jsonとIConfigurationで設定を外部化
    ↑今回紹介!
  • DI(依存性注入):依存関係を外から渡す設計手法
  • ログ:ILoggerによる構造化ログ
  • Host:設定・DI・ログを統合するアプリの骨格
プロ太

今回はC#で設定を外部化するモダンな方法を一緒に学んでいきましょう!

動画も作成しています。

講義:C#におけるモダンな設定管理の方法

なぜ「設定外部化」が必要なのか?

ハードコーディングの問題点

設定値をコードに直接書いてしまうということがあるかと思います。

var apiUrl = "https://api.example.com";
var maxRetryCount = 3;
var debugMode = true;

これには以下の問題があります。

  • 環境ごとに変えられない
    開発環境と本番環境で異なるURLを使いたいので、コードを書き換えが必要
  • ビルドし直さないと変更できない
    設定を変えるたびにアプリを再ビルド
  • 本番用の秘密情報が混ざる
    APIキーやパスワードがソースコードに残り、外部へ流出
プロ美

確かに、URL変えるたびにビルドしなおすのは面倒だね…。

設定外部化のメリット

設定をコードの外に出すことで、以下のメリットが得られます。

  • 環境ごとに切り替えられる
    開発・ステージング・本番で異なる設定を使い分けられる
    (※ 実行環境に応じた自動切り替えの仕組みは、後述する Host の回で紹介)
  • 再デプロイせずに変更できる
    設定ファイルを書き換えるだけで動作を変えられる
  • セキュリティ的に安全
    秘密情報をソースコードから分離できる
プロ太

設定はコードではない」という考え方が重要ですね。

設定は実行環境によって変わるもの、コードはどの環境でも同じ動作をするもの、と分けて考えます。

C#における設定管理の全体像

設定管理は以下の要素で構成されています。

  1. 設定ソース:設定値の置き場所(appsettings.json、環境変数など)
  2. IConfiguration:設定値を読み取るための統一インターフェース
  3. Builder:複数の設定ソースをまとめて IConfiguration を構築する
プロ美

appsettings.jsonってBlazorアプリで見たことある!

プロ美

あれ、でもコンソールアプリとかWPFアプリで無かったような?

プロ太

この設定管理方法は、どのようなC#アプリでも使えます

ただ、もともとテンプレートに含まれているもの(例:Blazor)、そうでないもの(例:コンソールアプリ)がありますね。

含まれてない場合も、自分で追加すればおなじ仕組みが使えます。

①から③をそれぞれみていきましょう。

①設定ソース:appsettings.jsonなど

最初に、設定値の置き場所である設定ソースについて見ていきます。代表的な設定ソースが 「appsettings.json」です。以下が具体例です。

{
  "AppSettings": {
    "AppName": "Sample App",
    "ApiBaseUrl": "https://api.example.com",
    "MaxRetryCount": 3
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

appsettings.jsonの特徴は以下の通りです。

  • JSON 形式:人間にも読みやすく、多くのツールでサポート
  • 階層構造:設定をカテゴリごとに整理可能
  • 環境別ファイル:環境ごとに異なる設定ファイルを用意可能

開発環境用に少し設定を修正・追加したい場合は、例えば以下のようなappsettings.Development.jsonといったファイルを別途用意します。

{
  "AppSettings": {
    "ApiBaseUrl": "https://dev-api.example.com"
  }
}

ポイントは「差分だけ書けばよい」ということです。appsettings.jsonで基本設定を定義し、環境別ファイルで変更したい部分だけが、実行時に上書きされます

appsettings.jsonを含め、以下のような様々な設定ソースを用意し、それらの読み込み優先度を決めたうえで、使うことが可能です。

設定ソース用途
JSONファイル(appsettings.json /
appsettings.{Environment}.json)
アプリ基本設定を記述する標準的な設定ファイル
(※appsettings.{Environment}.jsonの切り替えはHostを使うことが多い)
環境変数デプロイ先のサーバで設定。Docker や CI/CD と相性が良い
コマンドライン引数実行時に一時的に上書きしたい場合
User Secrets開発時のみ使う秘密情報(APIキーなど)
Azure Key Vault本番環境での機密情報管理。APIキーや接続文字列をクラウド上で安全に一元管理
プロ美

こんなに設定ソースがあったら、どういうふうに管理すればいいの?

プロ太

安心してください!これらは全部「IConfiguration」から一元的に読み取り可能なんです!

.NET Framework では、コンソールアプリやWPFでapp.config、ASP.NET で web.configといったXMLベースのアプリ構成ファイルが標準的でした。

現在の.NET(.NET Core 以降)では、appsettings.jsonなどJSONを中心とした構成ファイルがテンプレートで標準採用されています。

②IConfiguration:設定の読み取り口と、③Builder:設定を自動でまとめる仕組み

IConfigurationは、設定値をキーと値で取得するための共通インターフェースです。

設定がどこに保存されているか(JSONファイル、環境変数、コマンドライン引数など)を意識せずに、統一的な方法で設定値を取得できます。

設定値は、キーを指定して取得します。階層は : で区切ります。以下のように読み取ります。(取得される値は常に string 型です。数値として使いたい場合は変換が必要です。)

using Microsoft.Extensions.Configuration;

// 設定ビルダーを使用して設定を構築
IConfiguration config = new ConfigurationBuilder()
    .SetBasePath(AppContext.BaseDirectory) // アプリのディレクトリを基準パスに設定
    .AddJsonFile("appsettings.json")  // 設定ソース(1): JSONファイル
    .AddEnvironmentVariables() // 設定ソース(2): 環境変数
    .Build();

// 設定から "AppSettings:AppName" の値を取得
string appName = config["AppSettings:AppName"];
Console.WriteLine($"AppName: {appName}");

後に追加した設定ソースが優先(上書き)されます。

「AppSettings:AppName」として、以下のJSONファイル(appsettings.json)の値を読み取ります。

{
  "AppSettings": {
    "AppName": "Sample App",
...

もし、環境変数で以下のように「AppSettings__AppName」(階層は__で区切る)を設定しておけば、そちらの値が優先されます。以下はCLI、VS上でそれぞれ設定する例です。

 $Env:AppSettings__AppName = "Sample App (Debug)"
プロ美

なるほど、一元的にXX:YY:ZZ…」と指定できるんだね!設定ソースと優先順位も自分で決められるんだ!

プロ太

その通りですね。この仕組みによって、かなり柔軟に環境ごとの設定値の読み込みを制御できます!

Microsoft.Extensions.Configuration.Binderパッケージを追加すると、config.GetValue<T>で型変換したものを取得することも可能です。

より高度な型変換や設定クラスへのバインドについては、Optionsパターンで扱います(これは別の回で紹介する予定です)。

設定管理の全体像についてはMicrosoft Learnの「.NETでの構成」の記事も参考にしましょう。

演習:API設定を段階的に上書きする

以下のような「外部 API を呼び出すアプリの設定を管理」を例として、実際に設定管理部分を実装して、動作確認をしてみましょう。

  • appsettings.json に基本設定(APIのベースURL、タイムアウト秒数)
  • User Secrets に開発用の APIキー(ソースコードに含めたくない)
  • 環境変数 で一時的にデバッグモードを有効化

以下の手順で実装します。

  • 手順1:プロジェクト作成と必要なパッケージの追加
  • 手順2:appsettings.json の作成
  • 手順3:.csproj にコピー設定を追加
  • 手順4:User Secrets の初期化と設定
  • 手順5:Program.cs の実装

手順1:プロジェクト作成と必要なパッケージの追加

Visual Studioでコンソールアプリのプロジェクトを作成します。(今回VS2026、.NET10で作ります)プロジェクト名は「ConfigSample」としました。

そして、以下のパッケージをインストールします。

  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.EnvironmentVariables
  • Microsoft.Extensions.Configuration.UserSecrets

NuGetパッケージのインストール方法は以下を参考にしてください。

C#入門編(18)NuGetパッケージの使い方 ~CSVファイルを読み込む~【Visual Studio+nuget】 C#入門編です。今回はNuGetパッケージの使い方を紹介します。 実践的なアプリ開発では、他人が作った既存部品をいかにうまく使う...

手順2:appsettings.json の作成

プロジェクトフォルダにappsettings.json 作成します。

{
  "ApiSettings": {
    "BaseUrl": "https://api.example.com",
    "TimeoutSeconds": 30,
    "ApiKey": "(not set)",
    "DebugMode": false
  }
}

手順3:.csproj にコピー設定を追加

ConfigSample.csprojへ以下のようにappsettings.jsonのコピー設定を追記しましょう。これでバイナリ出力時に、appsettings.jsonもコピーされます。

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net10.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.1" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.1" />
		<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.1" />
	</ItemGroup>

	<!--↓ここを追加-->
	<ItemGroup>
		<None Update="appsettings.json">
			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
		</None>
	</ItemGroup>

</Project>

コンソールアプリ(Microsoft.NET.Sdk)ではこのような明示的な記述が必要です。

プロ太

ASP.NET Core Blazor(Microsoft.NET.Sdk.Web)など、もともとappsettings.jsonはビルド対象に含まれているものは記述不要です。

手順4:User Secrets の初期化と設定

以下のように、User Secrets の初期化と設定を行います。プロジェクトファイルがあるフォルダで以下のコマンドを実行しましょう。

dotnet user-secrets init
dotnet user-secrets set "ApiSettings:ApiKey" "dev-secret-key-12345"

これでUser SecretsとしてAPIキーを追加できました。

ちなみに、このAPIキーはWindowsであれば「%APPDATA%\Microsoft\UserSecrets\【プロジェクト個別GUID】\secrets.json」に格納されています。

手順5:Program.cs の実装

Program.cs の実装を以下のように実装します。優先順位は「環境変数>User Secrets>JSONファイル」です。

using Microsoft.Extensions.Configuration;
using System.Reflection;

IConfiguration config = new ConfigurationBuilder()
    .SetBasePath(AppContext.BaseDirectory)
    .AddJsonFile("appsettings.json")
    .AddUserSecrets(Assembly.GetExecutingAssembly())
    .AddEnvironmentVariables()
    .Build();

Console.WriteLine("=== API設定 ===");
Console.WriteLine($"BaseUrl: {config["ApiSettings:BaseUrl"]}");
Console.WriteLine($"TimeoutSeconds: {config["ApiSettings:TimeoutSeconds"]}");
Console.WriteLine($"ApiKey: {config["ApiSettings:ApiKey"]}");
Console.WriteLine($"DebugMode: {config["ApiSettings:DebugMode"]}");

アプリを実行

アプリをそのまま実行すると以下のように動作します。ApiKeyがUser Secretsの値で上書きされていることが確認できます。

=== API設定 ===
BaseUrl: https://api.example.com
TimeoutSeconds: 30
ApiKey: dev-secret-key-12345
DebugMode: False

次に環境変数で「ApiSettings__DebugMode」を”true”として実行してみましょう。例えば、プロジェクトフォルダ直下で以下のようにコマンド入力します。

❯ $Env:ApiSettings__DebugMode = "True"
❯ dotnet run
=== API設定 ===
BaseUrl: https://api.example.com
TimeoutSeconds: 30
ApiKey: dev-secret-key-12345
DebugMode: True

DebugModeがTrueで上書きされていることが確認できますね。

プロ美

設定ソースが優先順に沿ってちゃんと切り替わってるね!

プロ太

これですと、User Secretsの値はローカルにしか保存されない(コードベースに含まれない)ため、セキュリティ的にも安心ですね。

誤ってコードベースと一緒にGitHubへ流出する…といった事故も防げます。

Host(アプリの起動基盤)を使うと設定・DI・ログをまとめて構成してくれます。(ASP.NET Coreなどでは標準的に使われています)

実行環境(Development / Production)に応じたappsettingsの切り替えなども、このHostの仕組みの中で自然に行われます。

Hostについても、このシリーズの中で紹介予定です。

まとめ

今回はC#におけるモダンな設定管理の方法として、appsettings.jsonやIConfigurationを使った設定の外部化について学びました。

設定をコードの外に出すことで、環境ごとの切り替えが容易になり、再ビルドなしで設定変更ができ、秘密情報をソースコードから分離できるようになります。

設定管理は以下の3つの要素で構成されます。

  • 設定ソース
  • IConfiguration
  • Builder

appsettings.jsonや環境変数、User Secretsといった複数の設定ソースを、Builderがまとめ上げ、IConfigurationという統一インターフェースから読み取れる仕組みです。

設定値はAppSettings:ApiKeyのように階層を:で区切って指定し、後から追加した設定ソースが優先されます。

演習では、基本設定をappsettings.jsonに、開発用APIキーをUser Secretsに、デバッグモードを環境変数で管理する構成を実装しました。

このように設定ソースを使い分けることで、秘密情報の流出を防ぎつつ、柔軟な設定管理が実現できます。

次回は、設定管理と密接に関わる「DI(依存性注入)」について解説します。DIを使うことで、設定値をより効果的にアプリ全体で活用できるようになります。

プロ太

引き続き、モダンなC#開発における基盤について一緒に学んでいきましょう!

ABOUT ME
プロ太
ソフトウェア開発を楽しく、効率的に行う方法を追求しています。 開発者の視点から技術的課題に向き合い、「純粋な技術的興味に基づく探求」と「実践的な課題解決」という二つの柱を両輪として活動しています。