ビジュアライザーのアーキテクチャ
デバッガー ビジュアライザーのアーキテクチャには、次の 2 つの部分があります。
"デバッガー側" - Visual Studio デバッガー内で動作します。 デバッガー側のコードは、ビジュアライザーのユーザー インターフェイスを作成し、表示します。
"デバッグ対象側" - Visual Studio がデバッグしているプロセス (デバッグ対象) 内で動作します。
ビジュアライザーは、データ オブジェクトの内容を、意味のある理解しやすい形式で表示 ("視覚化") できるようにするためのデバッガーのコンポーネントです。 データ オブジェクトの編集をサポートするビジュアライザーもあります。 カスタム ビジュアライザーを作成すれば、独自のデータ型を処理できるようにデバッガーを拡張することも可能です。
視覚化対象であるデータ オブジェクトは、デバッグ中のプロセス ("デバッグ対象" プロセス) 内に存在します。 データを表示するユーザー インターフェイスは、Visual Studio デバッガー プロセス内で作成されます。
デバッガー プロセス | デバッグ対象プロセス |
---|---|
デバッガーのユーザー インターフェイス (データヒント、ウォッチ ウィンドウ、クイック ウォッチ) | 視覚化の対象となるデータ オブジェクト |
デバッガーのインターフェイス内でデータ オブジェクトを視覚化するには、2 つのプロセス間の通信を実現するためのコードを記述する必要があります。 したがって、ビジュアライザーのアーキテクチャは、"デバッガー側" コードと "デバッグ対象側" コードという、2 つの要素で構成されることになります。
デバッガー側コードでは、自身のユーザー インターフェイスが作成されます。このインターフェイスは、デバッガーのインターフェイス (データヒント、ウォッチ ウィンドウ、またはクイック ウォッチ) から呼び出すことができます。 ビジュアライザーのインターフェイスは、DialogDebuggerVisualizer クラスおよび IDialogVisualizerService インターフェイスを使用して作成します。 ビジュアライザーのすべての API に共通することですが、DialogDebuggerVisualizer および IDialogVisualizerService は、Microsoft.VisualStudio.DebuggerVisualizers 名前空間に存在します。
デバッガー側 | デバッグ対象側 |
---|---|
DialogDebuggerVisualizer クラス IDialogVisualizerService インターフェイス |
データ オブジェクト |
ユーザー インターフェイスは、視覚化の対象となるデータを、デバッガー側に存在するオブジェクト プロバイダーから取得します。
デバッガー側 | デバッグ対象側 |
---|---|
DialogDebuggerVisualizer クラス IDialogVisualizerService インターフェイス |
データ オブジェクト |
オブジェクト プロバイダー (IVisualizerObjectProvider を実装) |
デバッグ対象側には、対応するオブジェクトが存在します。これをオブジェクト ソースと呼びます。
デバッガー側 | デバッグ対象側 |
---|---|
DialogDebuggerVisualizer クラス IDialogVisualizerService インターフェイス |
データ オブジェクト |
オブジェクト プロバイダー (IVisualizerObjectProvider を実装) | オブジェクト ソース (VisualizerObjectSource から派生) |
オブジェクト プロバイダーは、視覚化の対象となるオブジェクト データをビジュアライザーの UI に提供します。 オブジェクト プロバイダーは、このオブジェクト データをオブジェクト ソースから取得します。 オブジェクト プロバイダーおよびオブジェクト ソースには、デバッガー側とデバッグ対象側との間でオブジェクト データをやり取りするための API が用意されています。
ビジュアライザーはすべて、視覚化の対象となるデータ オブジェクトを取得する必要があります。 次の表は、この目的で使用されるオブジェクト プロバイダーの API と、それに対応するオブジェクト ソースの API を示しています。
オブジェクト プロバイダー | オブジェクト ソース |
---|---|
GetData または GetObject |
GetData |
オブジェクト プロバイダーには、GetData と GetObject の 2 つの API が存在しています。 どちらの API を使用しても、オブジェクト ソースの GetData が呼び出されます。 Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource.GetData を呼び出すと、視覚化の対象となるオブジェクトがシリアル化されて System.IO.Stream に格納されます。
Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider.GetObject では、データがオブジェクト形式へと逆シリアル化されるため、このデータをそのまま DialogDebuggerVisualizer で作成した UI に表示できます。 Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider.GetData では、データが未加工の Stream
として格納されるため、これは別途、逆シリアル化する必要があります。 Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider.GetObject では、Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider.GetData を呼び出してシリアル化された Stream
を受け取り、そのデータを逆シリアル化するという処理が行われます。 オブジェクトを .NET でシリアル化できないなど、カスタムのシリアル化が必要な場合は、Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider.GetData を使用してください。 そのような場合は、Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource.Serialize メソッドをオーバーライドする必要があります。
読み取り専用のビジュアライザーを作成する場合は、GetData または GetObject を使った一方向の通信で十分です。 データ オブジェクトの編集をサポートするビジュアライザーを作成する場合、それだけでは不十分です。 オブジェクト プロバイダーからオブジェクト ソースへと、データ オブジェクトを戻す機能が必要となります。 次の表は、この目的で使用される、オブジェクト プロバイダーとオブジェクト ソースの API を示しています。
オブジェクト プロバイダー | オブジェクト ソース |
---|---|
ReplaceData または ReplaceObject |
CreateReplacementObject |
ここでも、オブジェクト プロバイダーには、使用できる API が 2 つ存在します。 データは常に Stream
としてオブジェクト プロバイダーからオブジェクト ソースへと送られますが、ReplaceData の場合は、別途、オブジェクトを Stream
にシリアル化する処理が必要となります。
ReplaceObject は、指定したオブジェクトを受け取り、それを Stream
にシリアル化した後、ReplaceData を呼び出して、Stream
を CreateReplacementObject に送ります。
いずれかの Replace メソッドを使用すると、視覚化対象であるオブジェクトを置き換える新しいデータ オブジェクトがデバッグ対象側に作成されます。 オブジェクトそのものを置き換えずに、元のオブジェクトの内容を変更する場合は、次の表に示した、いずれかの Transfer メソッドを使用してください。 これらの API では、視覚化対象であるオブジェクトを置き換えることなく、データが双方向で同時に転送されます。
オブジェクト プロバイダー | オブジェクト ソース |
---|---|
TransferData または TransferObject |
TransferData |