I did a quick introduction talk on Visual Studio Debugger Visualisers the other day, and one question I was asked was [something like] "Do you have to serialise the object to be visualised? Could you pass it to the visualiser and have it read the properties via reflection?"
The answer is yes and no. You do have to serialise the object to a stream, but you can implement your own method of serialisation. I'll try to explain that; the data to be visualised must pass between the process boundaries of the running process and the debugger process via a System.IO.Stream. The contents of this stream can be whatever you want, as long as the visualiser knows how to interpret it. Here's an example:
** If you haven't seen debugger visualisers before, check out my previous post here to give some background **
This is the object to be visualised:
Note the second argument to the DebuggerVisualiser attribute - this is vital to ensure that the correct class is used to provide the object to be visualised.
As the object is not marked as serialisable, it can't be provided to the visualiser via the normal GetObject method of the IVisualObjectProvider (the GetObject method relies on serialisation). However, what you can do is create a custom implementation of VisualizerObjectSource, to be used by the objectProvider. VisualiserObjectSource has a virtual method, GetData, with two parameters. The first parameter is an object, which will be the object to be visualised. The second parameter is a stream, which needs to be populated with the visualisation data for the object:
In this example, I'm passing an integer which represents the Argb value of the object's colour.
When the Show method on the visualiser is called, it's passed an instance of IVisualizerObjectProvider. With XML serialisable objects you would normally obtain the object to be visualised via the objectProvider.GetObject method. When the object is not serialisable, you need to call the GetData() method instead; the objectProvider calls the GetData method of the VisualizerObjectSource, and returns the contents of its outgoingStream argument. This can then be used to visualise the object:
When this is all put together, the visualiser looks like this:
The code from this example is on GitHub: https://github.com/orangutanboy/Visualiser-Demo-With-Custom-ObjectSource