ObjectVisualization を再設計して、デバッガビジュアライザー化しました!

以前紹介させていただきました ObjectVisualization という視覚化ツールなのですが、再設計してほぼ全入れ替えなレベルで実装し直しました!

目次

どういうやつ?

基本的な説明は GitHub に書きましたので、そちらをぜひご覧ください。

サンプルその6

ということなので、ここでは開発秘話などを書きたいと思います。

破壊的変更

実際の業務コードや大切なコードは、できる限り触りたくない、有意義ではない変更をソースに加えたくない!というのが実際の本音な気がします。旧バージョンではどうしてもソースコードに表示命令を書かないと使えないので、あまりイイ感じではないなと思っておりました。

元々は、Visual Studio と LINQPad のバイパス役が欲しい!という趣旨から始まっていたりするのですが、あれこれ調べている最中に、デバッガビジュアライザーなる仕組みを知り、こちらにシフトしよう!という流れに決めました。一から作り直しです。

シリアライズしないとダメ仕様

デバッガビジュアライザーにインスタンスを渡す際、いったんインスタンスシリアライズして渡さないといけない仕様だということが分かりました。旧バージョンでは直接インスタンスWPF View に変換して表示していたので、ここを分ける必要がありました。

これにより、旧バージョンではあった再取得リンクという機能を捨てました。この機能は、永久に続くタイプのメンバーに対する一時停止みたいな機能で、以下のようなインスタンスを表示する際に表示していました。

例えば、コレクション系であれば、以下のような子データがまたコレクションで、その子データもまたコレクションで、、、と続く場合、4階層目でいったん停止させておいてリンクをクリックした際に、再度取得して表示させる、みたいな機能でした。クリックイベント内にインスタンスを保持しておいて実現させていました。

List<T>
  List<T>
    List<T>
      List<T>
        List<T> ←★ここでリンクに変えて止めていた

メンバーの場合も、こういうのがあるので、同様にクリックイベント内にインスタンスを保持しておいて実現させていました。

Point
int:   X
int:   Y
Point: Empty -> Point
                int:   X
                int:   Y
                Point: Empty -> Point
                                int:   X
                                int:   Y
                                Point: Empty -> Point
                                                int:   X
                                                int:   Y
                                                Point: Empty
                                                ...

これが、いったんシリアライズしないといけない仕様に合わせるために、イイ感じの対応が思い浮かばなかったため、捨てることに決めました。

シリアライズ機能を探したんだけど・・・

一番良いのは、シリアライズしてデシリアライズして、object -> WPF View への変換して画面表示!という、何事もなかったかのように旧バージョンみたいに振舞うのがベストだったのですが、そのためのシリアライザーを見つけることができませんでした。悲しい・・・。調べてみると、遅い・速いがあったり(速い方が良いけど)、クラスやメンバーに属性を付けなければいけなかったり(渡されたクラス型はユーザーコード側になるため、こちらからはいじれない)、などが分かりました。

また、デバッガビジュアライザーには Stream で渡すのですが、データ量が多いと(というよりは処理時間がかかると?)タイムアウトしたり(しかもこちらから ReadTimeout や WriteTimeout をいじったら未対応ですと言われる)、または Stream には適当な少量のダミー文字列を渡しておいて、本データはテキストファイルに書き込んでおいて、Stream を読み込む側でテキストファイルを読み込んでみて、というのもやってみたのですが Stream で謎のエラーが出てしまったりで(こちらはもう調べる気にもならなかったり)、問題との格闘の日々でした。

で、どうしたかというと・・・

最終的には、自前定義の方向でいったん落としどころを付けた感じでした(シリアライザー探しは諦めました)。で、最小データで、型名と値を渡したいと考えたとき、json だとデータのみになってしまうため、型情報もくっつけるとしたらひと手間かかるので(あまり時間をかけたくなかったので)、xml が無難かなということで xml 形式の変換処理に決めました。例えばこんなのです。

<Primitive Type="string" Color="Brown">xxx</Primitive>

object -> string への変換処理で表示レシピを作っておいて、string -> WPF View への変換処理ではレシピ通りに作るだけ、という方向性を目指しています(気持ちだけは)。

もっと良い案があればいいのですが・・・、いや別に最終的にはこの案に決めたわけなので不満は無くて、自信を持って実装していますよ!

最後に

話の起承転結がグダグダですが、つまりは以下です。

もし少しでも面白そうだなと思われた際は、ぜひお試しください!