# 機能設計書 1-AvaloniaObject

## 概要

本ドキュメントは、Avaloniaフレームワークの依存関係プロパティシステムの基底クラスである`AvaloniaObject`の機能設計を記述する。WPFの`DependencyObject`に相当するクラスであり、プロパティ値の管理とバインディングの基盤を提供する。

### 本機能の処理概要

`AvaloniaObject`は、Avaloniaフレームワークにおけるすべてのプロパティシステムの基盤となるクラスである。`AvaloniaProperty`を介したプロパティ値の取得・設定、データバインディング、プロパティ値の継承、プロパティ変更通知など、UIフレームワークに不可欠な機能を提供する。

**業務上の目的・背景**：UIフレームワークにおいて、コントロール間のプロパティ値の共有、スタイリング、データバインディングを実現するためには、通常のCLRプロパティでは不十分である。`AvaloniaObject`は、プロパティ値の優先度管理（ローカル値、スタイル、アニメーション、継承値）、変更通知、バインディングソースへの接続など、宣言的UIを実現するための基盤を提供する。

**機能の利用シーン**：
- UIコントロールのプロパティ値の設定・取得
- XAMLでのデータバインディング設定時
- スタイルやテーマによるプロパティ値の適用
- アニメーションによるプロパティ値の変更
- 親要素からの継承プロパティ値の取得

**主要な処理内容**：
1. `GetValue`メソッドによるプロパティ値の取得（StyledProperty、DirectProperty両方に対応）
2. `SetValue`メソッドによるプロパティ値の設定（優先度指定可能）
3. `Bind`メソッドによるデータバインディングの設定
4. `ClearValue`メソッドによるローカル値のクリア
5. `PropertyChanged`イベントによるプロパティ変更通知
6. `InheritanceParent`による継承階層の管理
7. `SetCurrentValue`によるバインディングを破壊しない値設定

**関連システム・外部連携**：
- `ValueStore`：プロパティ値の内部ストレージ
- `AvaloniaPropertyRegistry`：プロパティ定義のレジストリ
- `Dispatcher`：UIスレッドアクセス検証
- `INotifyPropertyChanged`：標準的なプロパティ変更通知インターフェース

**権限による制御**：特になし（フレームワーク基盤クラス）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は全画面の基盤となるクラスであり、特定の画面に紐づかない |

## 機能種別

フレームワーク基盤 / プロパティシステム / データバインディング基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| property | AvaloniaProperty | Yes | 操作対象のプロパティ | null不可 |
| value | object? / T | Yes | 設定するプロパティ値 | UnsetValueType、DoNothingTypeは特殊処理 |
| priority | BindingPriority | No | プロパティ値の優先度 | Animation〜Inherited未満の範囲 |
| source | IObservable | Yes | バインディングソース | null不可 |

### 入力データソース

- アプリケーションコードからの直接呼び出し
- XAMLパーサーからのプロパティ設定
- バインディングシステムからの値更新
- スタイルシステムからの値適用
- アニメーションシステムからの値更新

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| プロパティ値 | object? / T | GetValueで取得されるプロパティの現在値 |
| IDisposable | IDisposable? | SetValue/Bindで返される、値設定を取り消すためのDisposable |
| PropertyChangedイベント | AvaloniaPropertyChangedEventArgs | プロパティ変更時に発火するイベント引数 |

### 出力先

- プロパティ変更通知イベントリスナー
- INotifyPropertyChanged実装によるバインディングターゲット
- 継承階層の子要素

## 処理フロー

### 処理シーケンス

```
1. GetValue(property)の呼び出し
   └─ プロパティがDirectPropertyの場合はRouteGetValueで直接取得
   └─ StyledPropertyの場合はValueStoreから取得

2. SetValue(property, value, priority)の呼び出し
   └─ UIスレッド検証（VerifyAccess）
   └─ 優先度の検証
   └─ UnsetValueの場合はClearValue処理
   └─ DoNothingの場合は何もしない
   └─ ValueStore.SetValueで値を設定

3. Bind(property, source, priority)の呼び出し
   └─ UIスレッド検証
   └─ 優先度の検証
   └─ BindingBaseの場合はBindingExpressionを作成
   └─ ValueStoreにバインディングを追加

4. プロパティ値変更時
   └─ OnPropertyChangedCoreの呼び出し
   └─ 有効値変更の場合はOnPropertyChangedの呼び出し
   └─ PropertyChangedイベントの発火
   └─ INPCイベントの発火
```

### フローチャート

```mermaid
flowchart TD
    A[SetValue呼び出し] --> B{UIスレッド?}
    B -->|No| C[例外スロー]
    B -->|Yes| D{優先度検証}
    D -->|無効| E[例外スロー]
    D -->|有効| F{値の種類?}
    F -->|UnsetValue| G[ClearValue]
    F -->|DoNothing| H[何もしない]
    F -->|通常値| I[ValueStore.SetValue]
    I --> J[プロパティ変更検出]
    J --> K{値が変更?}
    K -->|No| L[終了]
    K -->|Yes| M[OnPropertyChangedCore]
    M --> N[イベント発火]
    N --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | UIスレッドアクセス | プロパティ操作はUIスレッドからのみ許可 | 常時 |
| BR-02 | 優先度制約 | BindingPriorityはAnimation以上、Inherited未満 | SetValue時 |
| BR-03 | Equals/GetHashCodeオーバーライド禁止 | AvaloniaObjectのEquals/GetHashCodeはsealedでオーバーライド不可 | 常時 |
| BR-04 | 継承プロパティ伝播 | InheritanceParent変更時に継承プロパティ値を再評価 | 継承階層変更時 |

### 計算ロジック

プロパティ値の有効値は以下の優先度順で決定される：
1. Animation（最高優先度）
2. LocalValue
3. Style Trigger
4. Template
5. Style
6. Inherited
7. Unset（デフォルト値）

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

該当なし（メモリ内データ構造のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidOperationException | UIスレッド以外からのアクセス | UIスレッドから呼び出す |
| - | ArgumentException | 無効な優先度指定 | 有効な優先度範囲を使用 |
| - | ArgumentNullException | 必須パラメータがnull | パラメータを確認 |
| - | ArgumentException | 読み取り専用プロパティへのBind | 読み取り可能なプロパティを使用 |

### リトライ仕様

該当なし

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

該当なし（メモリ内操作のみ）

## パフォーマンス要件

- プロパティ取得・設定は同期的に完了すること
- ValueStoreの検索は効率的に行われること（内部で最適化済み）
- 継承プロパティの伝播は遅延評価されること

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

- UIスレッドアクセス検証によりスレッドセーフ性を確保
- プロパティ値の変更はフレームワーク管理下で行われる

## 備考

- WPF互換の設計思想に基づくが、Reactive Extensions対応など独自拡張あり
- `AvaloniaObject`を直接継承することは稀で、通常は`StyledElement`以下を使用

---

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

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

### 推奨読解順序

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

プロパティシステムの基盤となるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AvaloniaProperty.cs | `src/Avalonia.Base/AvaloniaProperty.cs` | プロパティの定義と識別子（Id）の管理方法 |
| 1-2 | BindingPriority.cs | `src/Avalonia.Base/Data/BindingPriority.cs` | プロパティ値の優先度列挙 |

**読解のコツ**: `AvaloniaProperty`はプロパティの「定義」を表し、`AvaloniaObject`はプロパティの「値」を保持することを意識する。

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

`AvaloniaObject`のコンストラクタと主要メソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AvaloniaObject.cs | `src/Avalonia.Base/AvaloniaObject.cs` | コンストラクタでのValueStore初期化 |

**主要処理フロー**:
1. **35-39行目**: コンストラクタでUIスレッド検証とValueStore初期化
2. **127-132行目**: `ClearValue`メソッドによるローカル値クリア
3. **217-225行目**: `GetValue`メソッドでの値取得（DirectProperty vs StyledProperty分岐）
4. **308-350行目**: `SetValue`メソッドでの値設定処理

#### Step 3: 値ストレージ層を理解する

プロパティ値の実際の保存と優先度管理を行うValueStoreを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ValueStore.cs | `src/Avalonia.Base/PropertyStore/ValueStore.cs` | 値の保存と優先度による有効値計算 |
| 3-2 | EffectiveValue.cs | `src/Avalonia.Base/PropertyStore/EffectiveValue.cs` | 有効値の管理 |

**主要処理フロー**:
- **ValueStore.GetValue**: 優先度を考慮した有効値の取得
- **ValueStore.SetValue**: 指定優先度での値設定

#### Step 4: 変更通知を理解する

プロパティ変更時の通知メカニズムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AvaloniaObject.cs | `src/Avalonia.Base/AvaloniaObject.cs` | OnPropertyChangedCore/OnPropertyChangedメソッド |
| 4-2 | AvaloniaPropertyChangedEventArgs.cs | `src/Avalonia.Base/AvaloniaPropertyChangedEventArgs.cs` | 変更通知イベント引数 |

**主要処理フロー**:
- **720-726行目**: `OnPropertyChangedCore`で有効値変更時に`OnPropertyChanged`呼び出し
- **778-801行目**: `RaisePropertyChanged`で各種イベント発火

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

```
AvaloniaObject
    │
    ├─ ValueStore（プロパティ値の保存と管理）
    │      ├─ EffectiveValue（各プロパティの有効値）
    │      └─ BindingEntry（バインディング情報）
    │
    ├─ AvaloniaPropertyRegistry（プロパティ定義の登録）
    │      └─ DirectPropertyBase/StyledProperty（プロパティ定義）
    │
    └─ Dispatcher.UIThread（スレッド検証）
```

### データフロー図

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

SetValue(property, value)
        │
        ▼
   VerifyAccess() ────▶ UIスレッド検証
        │
        ▼
   ValidatePriority() ──▶ 優先度検証
        │
        ▼
   ValueStore.SetValue() ─▶ 値の保存・有効値計算
        │
        ▼
   RaisePropertyChanged() ─▶ PropertyChangedイベント
                              INPCイベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AvaloniaObject.cs | `src/Avalonia.Base/AvaloniaObject.cs` | ソース | 依存関係プロパティシステムの基底クラス |
| AvaloniaProperty.cs | `src/Avalonia.Base/AvaloniaProperty.cs` | ソース | プロパティ定義の基底クラス |
| StyledProperty.cs | `src/Avalonia.Base/StyledProperty.cs` | ソース | スタイル適用可能なプロパティ |
| DirectPropertyBase.cs | `src/Avalonia.Base/DirectPropertyBase.cs` | ソース | 直接バッキングフィールドを持つプロパティ |
| ValueStore.cs | `src/Avalonia.Base/PropertyStore/ValueStore.cs` | ソース | プロパティ値の内部ストレージ |
| BindingPriority.cs | `src/Avalonia.Base/Data/BindingPriority.cs` | ソース | 優先度定義 |
| AvaloniaPropertyRegistry.cs | `src/Avalonia.Base/AvaloniaPropertyRegistry.cs` | ソース | プロパティ登録レジストリ |
