# 機能設計書 37-Microsoft.Extensions.Options

## 概要

本ドキュメントは、Microsoft.Extensions.Options（オプションパターン）機能の設計内容を記述する。この機能は設定値を厳密に型付けされたPOCOオブジェクトにバインドし、DIを通じてアクセス可能にする仕組みを提供する。

### 本機能の処理概要

Microsoft.Extensions.Optionsは、構成設定を型安全なクラスにバインドするオプションパターンの実装である。IOptions<T>、IOptionsSnapshot<T>、IOptionsMonitor<T>の3つのインターフェースを通じて、異なるライフタイムとリロード動作を提供する。

**業務上の目的・背景**：設定値を文字列キーでアクセスする方法は、型安全性がなく、リファクタリングが困難である。このライブラリは、設定を厳密に型付けされたクラスにバインドすることで、コンパイル時の型チェック、IntelliSense対応、リファクタリング容易性を提供する。設定の検証機能もサポートする。

**機能の利用シーン**：アプリケーション設定の読み込み、機能フラグの管理、データベース接続設定の管理、外部サービスURLの管理など、設定が必要なあらゆるシナリオで使用される。

**主要な処理内容**：
1. IOptions<T>によるシングルトンオプションアクセス
2. IOptionsSnapshot<T>によるスコープごとのオプションスナップショット
3. IOptionsMonitor<T>による設定変更の監視
4. 名前付きオプションによる複数設定の管理
5. IConfigureOptions<T>による設定デリゲート
6. IValidateOptions<T>による設定検証

**関連システム・外部連携**：Microsoft.Extensions.Configuration、Microsoft.Extensions.DependencyInjection、Microsoft.Extensions.Primitives（IChangeToken）と連携する。

**権限による制御**：オプション自体に権限制御はないが、設定値の読み込み元で制御可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに該当なし |

## 機能種別

データ連携 / 設定管理 / DIパターン

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | No | 名前付きオプションの名前 | null=DefaultName（空文字列） |
| configureOptions | Action<TOptions> | No | オプション設定デリゲート | - |
| section | IConfigurationSection | No | バインドする設定セクション | - |
| validateOptions | Func<TOptions, ValidateOptionsResult> | No | 検証関数 | - |

### 入力データソース

- IConfigurationからのバインディング
- ConfigureServicesでのプログラマティックな設定
- IConfigureOptions<T>実装

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Options | TOptions | 型付けされたオプションオブジェクト |
| ChangeToken | IChangeToken | 設定変更通知トークン |

### 出力先

- DIを通じたアプリケーションコード
- IOptions<T>.Value、IOptionsSnapshot<T>.Get()、IOptionsMonitor<T>.CurrentValue

## 処理フロー

### 処理シーケンス

```
1. サービス登録フェーズ
   └─ AddOptions<T>()、Configure<T>()でサービスを登録
2. オプション要求フェーズ
   └─ IOptions<T>等をDIから解決
3. ファクトリ呼び出しフェーズ
   └─ IOptionsFactory<T>.Create()でオプションインスタンスを生成
4. 設定適用フェーズ
   └─ IConfigureOptions<T>、IConfigureNamedOptions<T>を順番に適用
5. 後設定フェーズ
   └─ IPostConfigureOptions<T>を適用
6. 検証フェーズ
   └─ IValidateOptions<T>で検証
7. キャッシュフェーズ（IOptions/IOptionsSnapshot）
   └─ OptionsCache<T>にキャッシュ
8. 変更監視フェーズ（IOptionsMonitor）
   └─ IChangeTokenでリロードを監視
```

### フローチャート

```mermaid
flowchart TD
    A[AddOptions/Configure登録] --> B[IOptions等を解決]
    B --> C{解決インターフェース}
    C -->|IOptions| D[OptionsManager.Value]
    C -->|IOptionsSnapshot| E[OptionsManager.Get]
    C -->|IOptionsMonitor| F[OptionsMonitor.CurrentValue]
    D --> G[OptionsCache確認]
    E --> G
    F --> H[_currentValue確認]
    G --> I{キャッシュあり?}
    I -->|Yes| J[キャッシュから返却]
    I -->|No| K[IOptionsFactory.Create]
    H --> L{値あり?}
    L -->|Yes| M[現在値を返却]
    L -->|No| K
    K --> N[IConfigureOptions適用]
    N --> O[IPostConfigureOptions適用]
    O --> P[IValidateOptions実行]
    P --> Q{検証成功?}
    Q -->|Yes| R[オプション返却]
    Q -->|No| S[OptionsValidationException]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | IOptions<T>はSingleton | 一度生成されると変更されない | アプリケーション全体 |
| BR-37-02 | IOptionsSnapshot<T>はScoped | リクエストごとに設定を再読み込み | スコープ内 |
| BR-37-03 | IOptionsMonitor<T>はリアルタイム | 設定変更を即座に反映 | 常時 |
| BR-37-04 | 設定適用順序 | Configure→PostConfigure→Validate | オプション生成時 |
| BR-37-05 | 名前付きオプション | 同一型で複数の設定セットを管理可能 | Get(name)呼び出し時 |

### 計算ロジック

オプション生成順序：
1. new TOptions()でインスタンス生成
2. IConfigureOptions<TOptions>を登録順に適用
3. IConfigureNamedOptions<TOptions>を名前でフィルタして適用
4. IPostConfigureOptions<TOptions>を適用
5. IValidateOptions<TOptions>で検証

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | OptionsValidationException | 検証失敗時 | 設定値を修正 |
| - | MissingMethodException | パラメータなしコンストラクタがない | デフォルトコンストラクタを追加 |

### リトライ仕様

リトライなし（設定エラーは修正が必要）

## トランザクション仕様

該当なし

## パフォーマンス要件

- IOptions<T>.Value: 初回生成後はキャッシュからO(1)
- IOptionsSnapshot<T>.Get(): スコープ内でキャッシュ
- IOptionsMonitor<T>.CurrentValue: 変更時のみ再生成

## セキュリティ考慮事項

- 機密設定はUser SecretsまたはAzure Key Vaultを使用
- オプションクラスに機密情報を含める場合はログ出力に注意
- DataAnnotationsによる検証で入力値を検証可能

## 備考

- ValidateOnStartオプションで起動時検証が可能
- ValidateDataAnnotationsで[Required]等のアノテーション検証をサポート
- OptionsBuilder<T>でFluent APIによる設定が可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

オプションパターンの基本的なインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IOptions.cs | `src/libraries/Microsoft.Extensions.Options/src/IOptions.cs` | シングルトンオプションインターフェース |
| 1-2 | IOptionsSnapshot.cs | `src/libraries/Microsoft.Extensions.Options/src/IOptionsSnapshot.cs` | スコープオプションインターフェース |
| 1-3 | IOptionsMonitor.cs | `src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitor.cs` | 監視オプションインターフェース |
| 1-4 | IOptionsFactory.cs | `src/libraries/Microsoft.Extensions.Options/src/IOptionsFactory.cs` | オプションファクトリインターフェース |

**読解のコツ**: IOptions（Singleton）→IOptionsSnapshot（Scoped）→IOptionsMonitor（監視）の3つの違いを理解する。それぞれライフタイムと設定変更への対応が異なる。

#### Step 2: エントリーポイントを理解する

OptionsManagerとOptionsMonitorの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OptionsManager.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs` | IOptions/IOptionsSnapshot実装 |
| 2-2 | OptionsMonitor.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs` | IOptionsMonitor実装 |

**主要処理フロー**:
1. **OptionsManager.cs 33行目**: Valueプロパティで Get(Options.DefaultName) を呼び出し
2. **OptionsManager.cs 42-55行目**: Get()でキャッシュから取得またはファクトリで生成
3. **OptionsMonitor.cs**: IOptionsChangeTokenSourceを監視し、変更時にキャッシュをクリア

#### Step 3: ファクトリを理解する

オプション生成ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OptionsFactory.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs` | オプション生成ロジック |
| 3-2 | OptionsCache.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs` | オプションキャッシュ |

**主要処理フロー**:
- **OptionsFactory.Create()**: TOptionsを生成し、Configure→PostConfigure→Validateを適用
- **OptionsCache.GetOrAdd()**: ConcurrentDictionaryベースのキャッシュ

#### Step 4: 検証を理解する

オプション検証の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | IValidateOptions.cs | `src/libraries/Microsoft.Extensions.Options/src/IValidateOptions.cs` | 検証インターフェース |
| 4-2 | ValidateOptionsResult.cs | `src/libraries/Microsoft.Extensions.Options/src/ValidateOptionsResult.cs` | 検証結果 |
| 4-3 | OptionsValidationException.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsValidationException.cs` | 検証例外 |

### プログラム呼び出し階層図

```
IOptions<T>.Value / IOptionsSnapshot<T>.Get(name)
    │
    └─ OptionsManager<T>.Get(name)
           │
           ├─ OptionsCache<T>.TryGetValue(name)
           │      │
           │      └─ キャッシュにあれば返却
           │
           └─ OptionsCache<T>.GetOrAdd(name, factory.Create)
                  │
                  └─ IOptionsFactory<T>.Create(name)
                         │
                         ├─ new TOptions()
                         │
                         ├─ foreach IConfigureOptions<T>
                         │      └─ configure.Configure(options)
                         │
                         ├─ foreach IPostConfigureOptions<T>
                         │      └─ postConfigure.PostConfigure(name, options)
                         │
                         └─ foreach IValidateOptions<T>
                                └─ validate.Validate(name, options)

IOptionsMonitor<T>.CurrentValue
    │
    ├─ _currentValue確認
    │
    └─ IOptionsMonitorCache<T>.GetOrAdd(DefaultName, factory.Create)
```

### データフロー図

```
[入力]                      [処理]                        [出力]

Configure<T>() ───▶ IServiceCollection ───▶ IConfigureOptions<T>登録
                                                   │
                                                   ▼
IOptions<T>解決 ───▶ OptionsManager<T> ───▶ OptionsCache<T>.GetOrAdd()
                                                   │
                                                   ▼
                                    IOptionsFactory<T>.Create()
                                                   │
                          ┌────────────────────────┼────────────────────────┐
                          ▼                        ▼                        ▼
              IConfigureOptions<T>     IPostConfigureOptions<T>    IValidateOptions<T>
                          │                        │                        │
                          └────────────────────────┼────────────────────────┘
                                                   ▼
                                            TOptionsインスタンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OptionsManager.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs` | ソース | IOptions/IOptionsSnapshot実装 |
| OptionsMonitor.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs` | ソース | IOptionsMonitor実装 |
| OptionsFactory.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs` | ソース | オプション生成 |
| OptionsCache.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs` | ソース | キャッシュ |
| ConfigureOptions.cs | `src/libraries/Microsoft.Extensions.Options/src/ConfigureOptions.cs` | ソース | 設定実装 |
| PostConfigureOptions.cs | `src/libraries/Microsoft.Extensions.Options/src/PostConfigureOptions.cs` | ソース | 後設定実装 |
| ValidateOptions.cs | `src/libraries/Microsoft.Extensions.Options/src/ValidateOptions.cs` | ソース | 検証実装 |
| OptionsBuilder.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsBuilder.cs` | ソース | Fluentビルダー |
| OptionsServiceCollectionExtensions.cs | `src/libraries/Microsoft.Extensions.Options/src/OptionsServiceCollectionExtensions.cs` | ソース | DI拡張 |
