A arquitetura do debugger está dividida em duas partes:
- O debugger side corre dentro do debugger do Visual Studio .NET, podendo ser criado e exibido uma interface para seu visualizador.
- O debuggee side corre dentro do processo que o Visual Studio .NET está depurando.
O objeto que você está querendo visualizar (uma String ou Image, por exemplo) existe dentro do processo debuggee. Logo, o debuggee side deve mandar os dados para o debugger side que, por sua vez, exibe o objeto para que o desenvolvedor possa depurar. Essa visualização é criada por nós que, ainda nesse artigo, veremos como criá-la.
O debugger side recebe o objeto que será visualizado através de um object provider, o qual implementa uma interface chamada IVisualizerObjectProvider. O debuggee side envia o objeto através de um object source, o qual deriva de uma classe chamada VisualizerObjectSource. O object provider também devolve o objeto para o object source, permitindo assim, além de exibir o objeto, editá-lo no visualizador (se assim desejar) e devolvê-lo para a aplicação. Essa comunicação é efetuada através de um objeto Stream.
Para criarmos este visualizador, primeiramente precisamos marcar a classe como sendo uma classe de DebuggerVisualizer e, para isso, é fornecido um atributo chamado DebuggerVisualizer (usado a nível de assembly ou classe) para definí-la como um visualizador. Além disso, a classe deverá obrigatoriamente herdar de uma classe abstrata chamada DialogDebuggerVisualizer e implementar o método chamado Show para customizar a visualização.
O atributo DebuggerVisualizer, contido dentro do Namespace System.Diagnostics, fornece mais alguns parâmetros para a configuração do visualizador. O primeiro parâmetro é tipo, ou seja, a classe derivada DialogDebuggerVisualizer que é o nosso visualizador efetivamente; já o segundo especifica o tipo de objeto que fará a comunicação entre o debugger side e o debuggee side e, se não informado, um default será utilizado. O restante, chamado de “Named Parameters”, você deve especificar o tipo de objeto que o visualizador irá trabalhar (uma String ou Image, por exemplo) e no outro, é o nome que aparecerá dentro do Visual Studio .NET 2005, para permitir visualização. Para ilustrar, veremos abaixo o código que cria o visualizador:
using System; using Microsoft.VisualStudio.DebuggerVisualizers; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; [ assembly: DebuggerVisualizer(typeof(DebugTools.ImageVisualizer), typeof(VisualizerObjectSource), Target = typeof(System.Drawing.Image), Description = "Image Visualizer") ] namespace DebugTools { public class ImageVisualizer : DialogDebuggerVisualizer { protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) { Image data = (Image)objectProvider.GetObject(); using(ImageVisualizerForm f = new ImageVisualizerForm()) { f.Image = data; windowService.ShowDialog(f); } } } } |
Note que foi criado um formulário chamado ImageVisualizerForm. Este formulário é encarregado de receber a imagem e exibí-la. Não há segredos nele, ou seja, apenas foi criada uma propriedade chamada Image que recebe a imagem vinda do object provider. O primeiro parâmetro do método Show, chamado windowService do tipo IDialogVisualizerService, fornece métodos para que o visualizador possa estar exibindo formulários, controles e janelas de diálogo.
Se você quiser que o seu visualizador edite o objeto e o devolva para a aplicação, terá que sobrescrever os métodos TransferData ou CreateReplacementObject da classe VisualizerObjectSource.
Deploy
Para que possamos utilizar o visualizador dentro do Visual Studio .NET 2005 teremos que compilar o projeto e, com a DLL gerada, colocá-la dentro do diretório <Diretorio VS.NET>Common7PackagesDebuggerVisualizers. Quando abrir o Visual Studio, já terá acesso ao visualizador, assim como é mostrado através da imagem abaixo:
|
Figura 1 – DebuggerVisualizer em funcionamento. |