# 機能設計書 106-Razor連携

## 概要

本ドキュメントは、Roslyn における Razor 言語サポート統合機能の設計を記述する。この機能は ASP.NET Razor ファイル内の C# コードに対して Roslyn 言語サービスを提供する。

### 本機能の処理概要

Razor 連携機能は、.cshtml や .razor ファイル内に埋め込まれた C# コードに対して、IntelliSense、ナビゲーション、診断などの言語サービス機能を提供する。Roslyn のリモートホスト機能を利用して、Razor ツーリングと連携する。

**業務上の目的・背景**：ASP.NET 開発では、Razor ビューファイル内に C# コードを記述することが一般的である。開発者が Razor ファイル内でも通常の C# ファイルと同様の編集体験を得られるようにするため、Roslyn 言語サービスとの連携が必要である。

**機能の利用シーン**：Visual Studio で Razor ファイル（.cshtml, .razor）を編集している際に、C# コードブロックや式に対してコード補完、定義への移動、参照の検索などの機能を利用する場面で使用される。

**主要な処理内容**：
1. RazorLanguageServiceClientFactory による言語サービスクライアントの生成
2. RazorLanguageServiceClient によるリモート言語サービスへのアクセス
3. RemoteHostClient を通じた OOP（Out-of-Process）通信
4. TagHelper 解決などの Razor 固有機能との連携

**関連システム・外部連携**：Razor ツーリング（AspNetCore-Tooling）、RemoteHostClient、Roslyn OOP サービスと連携する。

**権限による制御**：特定の権限制御なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Razor エディタ | 主画面 | .cshtml/.razor ファイルの編集 |

## 機能種別

言語サービス統合 / リモート通信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| solution | Solution | No | ソリューション情報 | null の場合は null を返す |
| targetName | string | Yes | 呼び出すリモートメソッド名 | - |
| arguments | IReadOnlyList\<object?\> | Yes | メソッド引数 | - |

### 入力データソース

- Razor ファイルのテキストバッファ
- ソリューション情報
- RemoteHostClient

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Optional\<T\> | リモートメソッドの実行結果 |
| Session | Session | リモートセッション（Obsolete） |

### 出力先

- Razor ツーリング
- 言語サービス機能

## 処理フロー

### 処理シーケンス

```
1. Razor ツーリングがクライアントを要求
   └─ RazorLanguageServiceClientFactory を呼び出し
2. RemoteHostClient を取得
   └─ ワークスペースからリモートホストクライアントを取得
3. RazorLanguageServiceClient を生成
   └─ クライアントインスタンスを返却
4. リモートメソッドを呼び出し
   └─ TryRunRemoteAsync で OOP サービスに要求
5. 結果を返却
   └─ Optional<T> として結果を返す
```

### フローチャート

```mermaid
flowchart TD
    A[Razor ツーリング] --> B[RazorLanguageServiceClientFactory]
    B --> C[RemoteHostClient 取得]
    C --> D[RazorLanguageServiceClient 生成]
    D --> E{リモートメソッド呼び出し}
    E -->|TryRunRemoteAsync| F[OOP サービス実行]
    F --> G[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-106-01 | Null Solution 対応 | Solution が null の場合は null を返す | CreateSessionAsync 時 |
| BR-106-02 | 非推奨 API 維持 | 後方互換性のため Session ベースの API を維持 | Obsolete 属性付き |
| BR-106-03 | External Access 推奨 | 新規利用は RazorRemoteHostClient を推奨 | 新規開発時 |

### 計算ロジック

特になし

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

### 操作別データベース影響一覧

データベース操作なし

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | null 返却 | RemoteHostClient が取得できない | null を返して呼び出し元で処理 |
| - | 例外 | リモート呼び出し失敗 | 例外を伝播 |

### リトライ仕様

リトライなし（呼び出し元で対応）

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

トランザクションなし

## パフォーマンス要件

- OOP 通信による遅延を最小化
- 非同期処理による UI スレッドのブロック回避

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

- OOP 設計によるプロセス分離
- ローカルのソースコードのみを対象

## 備考

- このクラスは `[Obsolete]` 属性が付与されており、`Microsoft.CodeAnalysis.ExternalAccess.Razor.RazorRemoteHostClient` の使用が推奨される
- AspNetCore-Tooling リポジトリの OOPTagHelperResolver で使用される

---

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

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

### 推奨読解順序

#### Step 1: クライアントファクトリを理解する

まず、Razor 言語サービスクライアントの生成方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RazorLanguageServiceClientFactory.cs | `src/VisualStudio/Razor/RazorLanguageServiceClientFactory.cs` | クライアントファクトリの実装 |

**読解のコツ**: ファクトリパターンを使用しており、RemoteHostClient を取得して RazorLanguageServiceClient を生成する。

#### Step 2: クライアント実装を理解する

リモート言語サービスへのアクセス方法を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RazorLanguageServiceClient.cs | `src/VisualStudio/Razor/RazorLanguageServiceClient.cs` | クライアントの実装 |

**主要処理フロー**:
1. **19行目**: `[Obsolete]` 属性が付与されている
2. **20-28行目**: コンストラクタで RemoteHostClient と serviceName を受け取る
3. **30-31行目**: TryRunRemoteAsync でリモートメソッドを呼び出し
4. **33-59行目**: CreateSessionAsync（Obsolete）でセッションを作成
5. **61-85行目**: 内部クラス Session でセッションベースの呼び出しをサポート

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

```
RazorLanguageServiceClientFactory
    │
    └─ RazorLanguageServiceClient
           │
           ├─ TryRunRemoteAsync
           │      └─ _client.RunRemoteAsync
           │
           └─ CreateSessionAsync (Obsolete)
                  └─ SessionWithSolution.CreateAsync
                         └─ Session
                                ├─ InvokeAsync
                                └─ Dispose
```

### データフロー図

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

Razor ツーリング ────────▶ ClientFactory ─────────────────▶ Client
                               │
Solution + args ─────────▶ TryRunRemoteAsync ─────────────▶ Optional<T>
                               │
                          RemoteHostClient ────────────────▶ OOP Service
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RazorLanguageServiceClient.cs | `src/VisualStudio/Razor/RazorLanguageServiceClient.cs` | ソース | 言語サービスクライアント |
| RazorLanguageServiceClientFactory.cs | `src/VisualStudio/Razor/RazorLanguageServiceClientFactory.cs` | ソース | クライアントファクトリ |
| RemoteHostClient.cs | `src/Workspaces/Remote/Core/RemoteHostClient.cs` | ソース | リモートホストクライアント基盤 |
| SessionWithSolution.cs | `src/Workspaces/Remote/Core/SessionWithSolution.cs` | ソース | ソリューション付きセッション |
