Отладка при помощи средств визуализации отладчика (Debugger Visualizers) Visual Studio 2005 - Создаем специализированное cредство визуализации
ОГЛАВЛЕНИЕ
Создаем специализированное cредство визуализации
Создание специализированного cредства визуализации обычно подразумевает создание трех связанных объектов:
- класс cредства визуализации ("visualizer") - когда разработчик нажимает на иконку увеличительного стекла во время сессии отладки, мы должны каким-то образом связать соответствующий объект и отобразить информацию в желаемом формате. Действие получения информации объекта из отладчика и передачи ее в пользовательский интерфейс является ответственностью класса cредства визуализации. Данный класс наследуется от класса DialogDebuggerVisualizer и предоставляет метод Show() , который отвечает за получение информации и вызов пользовательского интерфейса. Данный класс также должен содержать атрибут сборки, обозначающий, что cредство визуализации является подходящего типа данных .
- класс источника ("source") - ответственностью класса источника является взятие объекта, чья иконка увеличительного стекла была нажата, и передача данной информации объекта в отладчик. Данный класс наследуется от VisualizerObjectSource и обладает методом GetData(object, Stream), который предоставляет сериализированную версию объекта классу cредства визуализации. В частности, первым входным параметром метода GetData() является объект, чья иконка увеличительного стекла была нажата; вторым входным параметром является Stream (поток), к которому объект должен быть сериализирован.
- пользовательский интерфейс ("user interface") - пользовательский интерфейс, который отобразит информацию. Обычно это подразумевает создание формы (либо нескольких), добавление соответствующих элементов пользовательского интерфейса (TextBoxe, TreeView, и т.д.), а также передачу классом cредства визуализации информации для отображения.
Давайте рассмотрим исходный класс. Метод GetData() здесь начинается с преобразования первого входного параметра в объект Page и затем сброса значений коллекции Request.ServerVariables в новую NameValueCollection. (Я произвожу данное детальное копирование, поскольку Request.NameValueCollection на самом деле является объектом типа HttpServerVarsCollection, который не является сериализированным, следовательно, не может быть переслан из исходного класса в класс cредства визуализации. Коллекция NameValueCollection является сериализируемой, тем не менее после сброса содержимого из Request.NameValueCollection в локальную NameValueCollection я затем сериализирую содержимое в поток (Stream), который был передан в качестве второго входного параметра):
public override void GetData(object target, System.IO.Stream outgoingData) { if (target != null && target is Page) { Page p = (Page)target; // Помещаем содержимое из Request.ServerVariables в // локальное NameValueCollection b/c Request.ServerVariables // не является сериализированным... NameValueCollection nvc = new NameValueCollection(); foreach (string key in p.Request.ServerVariables) nvc.Add(key, p.Request.ServerVariables[key]); // сериализация nvc в поток outgoingData BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(outgoingData, nvc); } } |
Далее, в методе Show() класса cредства визуализации мы десериализируем информацию из метода GetData() и создаем пользовательский интерфейс. Это выполняется при помощи данного кода:
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) { // Десериализация Stream возвращенного GetData() в NameValueCollection NameValueCollection vars = null; using (Stream dataStream = objectProvider.GetData()) { BinaryFormatter formatter = new BinaryFormatter(); vars = formatter.Deserialize(dataStream) as NameValueCollection; } // Создаем форму пользовательского интерфейса,передавая в NameValueCollection using (VisualizerForm displayForm = new VisualizerForm()) { displayForm.Visualize(vars); windowService.ShowDialog(displayForm); } } |
Класс VisualizerForm является Windows Form, содержащей элемент управления ListView. Метод Visualize(NameValueCollection) класса VisualizerForm (написанный мною), берет переданный объект NameValueCollection и сбрасывает его содержимое в ListView.
Также в класс cредства визуализации включен атрибут DebuggerVisualizer, который связывает средство с типом данных System.Web.UI.Page:
[assembly: DebuggerVisualizer( typeof(skmVisualizers.ServerVariables.Visualizer), typeof(skmVisualizers.ServerVariables.ServerVariablesControlSource), Target = typeof(System.Web.UI.Page), Description = "Visualize the page's server variables.")] |