Some time ago, Sergei Zvezdin (
sergun )
announced a brainstorm in order to generate a number of ideas for a possible implementation in the form of addons for Visual studio 2010. I described my Xaps Minifier and suggested another one. The idea was to use the Silverlight PivotViewer control to visualize the source code.
Theory
PivotViewer control can be used to visualize a large amount of data and allows you to filter and sort them by any criterion. Source code can be used as data that can be analyzed by developers / team leaders to find potential problem areas. By such places, I mean classes, methods that should be refactored. For example, it is very difficult to support a large class, method, etc. Obviously, such a code is refactored.
Thus, my addon should analyze the source code of the project, prepare the data for the PivotViewer control and display the control itself and the data in it.
High level architecture

There are several limitations when using the PivotViewer control.
- You should use the Silverlight version of the control, since There is no separate WPF version of this control. This is because WPF does not include the MultiScaleImage (Deep Zoom) mechanism.
- You should use a separate web server to host the Silverlight application in it, because PivotViewer control does not support local collections.
I will describe each step presented in the diagram.
- I should bypass all projects, classes, methods in order to get all the information about the source code of the application. This information will be used to build a picture in PivotViewer.
- I should deploy the web server infrastructure. This means creating folders for the web server and for the results of processing the source code, as well as placing the web server itself on disk.
- I should serialize and save the data that was obtained during the processing of the source code.
- I should start a web server that will host the Silverlight application with the PivotViewer control onboard. I'm going to use Cassini (a web server that is used to develop and debug web applications in Visual Studio). It is lightweight and comes with Visual Studio.
- The application starts and opens in the Web Browser tab inside Visual Studio.
- PivotViewer control starts loading data and transforms it into internal collections, which are then rendered.
Features of the implementation
Source code processing
I use the same technique that I use in the
XapsMinifier add-on to Visual Studio. I bypass all the project within the current loaded solution, all files within the project, all elements within the file - classes, interfaces, structures, etc. I create one big data set that contains all the necessary elements:
- Is the class abstract
- The number of parts that make up partial class / interface / structure
- Number of lines of class / interface / structure code
- The number of members (methods, properties, etc.) that contains the class / interface / structure
- Data item name
- The full name of the element (namespace + name)
- The path to the file that contains this data item.
- The name of the project where the item is located
- The programming language in which this element is written (C #, VB, Managed C ++, etc.)
Web server deployment
In accordance with my idea, you should place a web server for each project that is processed by this utility. Thus, I have to create a folder for the Silverlight application and for the file that contains the serialized data for the PivotViewer control. I create the
_PivotViewer folder in the same directory where the solution file is located. This folder will contain a file with serialized data (
PivotClassData.bin ) and a
Server folder with a ready Silverlight project.
')
I can rely on the post-build event of the
WebServer project to archive all the required files for publishing the web server (* .dll, * .aspx, etc.). This archive is connected to the
PackageTools project as an embedded resource.
Example:$(SolutionDir)Externals\7z.exe a -r -tzip -mx9 <br> $(SolutionDir)PackageTools\Resources\WebServer.zip $(ProjectDir)* -x!obj <br> -x!properties -x!.svn -x!_svn -x!*.csproj -x!*.csproj.user <br> -x!*.publish.xml -x!*.bat -x!*.cs -x!*.designer.cs -x!*.pdb <br><br> * This source code was highlighted with Source Code Highlighter .
I unpack the archive into the
Server folder using the
ICSharpCode.SharpZipLib library.
Data serialization
I use binary serialization to minimize the size of the data file and speed up the processing.
Web server launch
I use the following command line to run Cassini.
Example:"C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.EXE" <br> /port:8899 /path:" < path_to_solution_folder > \_PivotViewer\Server" /vpath:"/" <br><br> * This source code was highlighted with Source Code Highlighter .
This command will launch the web server relative to the
<solution_path> \ _ PivotViewer \ Server folder and the web site will be accessible at
http: // localhost: 8899 .
Application launch
I use the standard Visual studio extension interface to open the Web Browser tab and navigate to the required path (
http: // localhost: 8899 ).
Example:IVsWindowFrame frame;<br>IVsWebBrowsingService webVrowserService = this .GetService( typeof (SVsWebBrowsingService))<br> as IVsWebBrowsingService;<br>webVrowserService.Navigate( "http://localhost:8899/SilverlightPivotViewerTestPage.aspx" ,<br> ( uint )__VSCREATEWEBBROWSER.VSCWB_FrameMdiChild, out frame); <br><br> * This source code was highlighted with Source Code Highlighter .
Data loading
I do not use
simple or related collections . they require many preliminary steps. I use the just-in time collection and the
Pivot_JIT_Sample application to build a
JIT collection server. I implement the
CollectionFactoryBase
class that reads the serialized data from a file and builds the JIT collection.
Example:private void MakeCollectionItem(PivotClassElementsData item, Collection collection)<br>{<br> Guard.ArgumentNotNull(item, "item" );<br> Guard.ArgumentNotNull(collection, "collection" );<br><br> collection.AddItem(item.Name, null , null ,<br> null <br> , new Facet( "Lines count" , item.CodeLinesCount)<br> , new Facet( "Is Static Class" , item.IsStatic.ToString())<br> , new Facet( "File path" , item.Path)<br> , new Facet( "Parts count" , item.PartsCount)<br> , new Facet( "Full name" , item.FullName)<br> , new Facet( "Language" , item.Language)<br> , new Facet( "Members count" , item.MembersCount)<br> , new Facet( "Class Name" , item.Name)<br> , new Facet( "Project name" , item.ProjectName)<br> //, new Facet("# of switch statements", item.SwitchCount) <br> );<br><br> collection.SetFacetDisplay( "File path" , false , true , true );<br> collection.SetFacetDisplay( "Full name" , false , true , true );<br> collection.SetFacetFormat( "Lines count" , "0" );<br> collection.SetFacetFormat( "Parts count" , "0" );<br> collection.SetFacetFormat( "Members count" , "0" );<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .
I do not display some parameters in the filtering area (“File path”, “Full name”), but they are available on the information panel.
Installation and use
This extension can be installed via the
Visual Studio Extension Manager (Main menu-Tools-Extension Manager-Online Gallery) using the online extension store. The current version of the application is 0.9 beta.
In order to launch the visualization of the solution, open it in Visual studio, right-click on the solution itself in the Solution Explorer and select the menu item
Solution Pivot Viewer .

As soon as this action is triggered, the extension will begin to parse the source code, receive data for the PivotViewer control, deploy the web application with the Silverlight PivotViewer control and open the web page of the application.

Having played with this extension, you can quickly and clearly get information about the application and its source code.
Known issues / limitations
Since this is a beta version, the extension has certain limitations and known problems.
- Only one collection is supported - classes / interfaces / structures
- The extension cannot determine whether the Cassini server is running or not, and therefore an exception may occur that, however, does not affect the main function of the application.
- It uses a hard-coded port for Cassini - 8899. This means that for the expansion to work, you must make sure that the port is open and not busy
- Requires an installed Cassini server on the computer
- The application has no interface for displaying the progress of the operation or displaying the settings.
Future plans
- Add a wizard to configure the application
- Add new collection types (files, members)
- Add screen printing feature
- Add support for MEF-based extensions to support the computation of various metrics
Source texts
The sources for this extension are available
here .
Leave your opinion
I would be very interested to know your opinion about this extension, what features to add, what to change, etc. Contact us!