Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Peer Code Review Add-in for Visual Studio 2008 - ReviewMyCode

4.00/5 (3 votes)
7 Oct 2011CPOL3 min read 31.1K   511  
Peer code reviews are a proven way to improve software quality. ReviewMyCode helps you overcome some barriers to this best practice with a simple Visual Studio 2008 add-in that fits your process.

Introduction

Peer code reviews are a proven way to improve software quality. ReviewMyCode helps you overcome some barriers to this best practice with a simple Visual Studio 2008 add-in that fits your process. The team members can contribute to the review process without leaving the development environment.

The add-in works well within a team development environment by integrating the review process with the SVN source control management system.

Background

Getting Started with Extending Visual Studio is a good starting point for Visual Studio add-in development.

Using the Code

An add-in must have at least two files, the add-in descriptor XML file and the assembly which implements the actual add-in. The descriptor file describes the add-in assembly and is located in the user's %USERPROFILE%\Documents\Documents\Visual Studio 2008\Addins folder.

A typical add-in descriptor XML file looks like this:

XML
<Extensibility xmlns="http://schemas.microsoft.com/AutomationExtensibility">
	<HostApplication>
		<Name>Microsoft Visual Studio</Name>
		<Version>9.0</Version>
	</HostApplication>
	<Addin>
		<FriendlyName>ReviewMyCode</FriendlyName>
		<Description>Review My Code</Description>
		<Assembly>ReviewMyCode.dll</Assembly>
		<FullClassName>ReviewMyCode.View.Connect</FullClassName>
		<LoadBehavior>1</LoadBehavior>
		<CommandPreload>0</CommandPreload>
		<CommandLineSafe>0</CommandLineSafe>
	</Addin>
</Extensibility>

The Extensibility\Addin\Assembly gives the path to the add-in assembly. With just the file name, Visual Studio will load the add-in assembly from the add-in descriptor folder. If you need to debug the add-in, you need to point it to the debug build of your add-in. Also you need to set up debug properties of the Visual Studio project to start Visual Studio as an external program. Make sure to specify:/resetaddin ReviewMyCode.View.Connect as the command line arguments.

The entry point of an add-in is the Connect class. It implements Extensibility.IDTExtensibility2 interface. The OnConnection method receives notification that the add-in is being loaded and we perform our initialization code here, such as creation of the solution event (Solution Open, Solution Before Closing) delegates. In order to handle solution level events the delegates must be defined in the Connect class.

The OnStartupComplete method receives notification that the host application has completed loading, in which we create our tool window (add-in window) and shows it. The add-in window is a UserControl.

The rest of the classes are just implementing the logic and the UI. Retrieving information about the code being reviewed depends on the selected line. The following code snippet shows the details:

C#
private void ToolStripReviewItemAddNew_Click(object sender, EventArgs e)
{
    TextPoint textPoint = null;
    TextSelection selection = 
        Connect.ApplicationObject.ActiveDocument.Selection as TextSelection;
    if (selection != null)
    {
        textPoint = selection.ActivePoint as TextPoint;
        if (textPoint != null)
        {
            this.textBoxLineNumber.Text = 
            	textPoint.Line.ToString(CultureInfo.CurrentCulture);
        }
    }
    
    CodeElement codeElement = null;
    FileCodeModel2 fileCodeModel =
        Connect.ApplicationObject.ActiveDocument.ProjectItem.FileCodeModel 
				as VCFileCodeModel;
    if (fileCodeModel == null)
    {
        fileCodeModel = Connect.ApplicationObject.ActiveDocument.
        		ProjectItem.FileCodeModel as FileCodeModel2;
    }
    
    if (textPoint != null && fileCodeModel != null)
    {
        // Supported scopes - set up here in the right parsing order
        // from lowest level to highest level.
        // NOTE: Must be adjusted to match any CodeElements supported.
        vsCMElement[] scopes = 
            {
               vsCMElement.vsCMElementFunction,
               vsCMElement.vsCMElementProperty,
               vsCMElement.vsCMElementVariable,
               vsCMElement.vsCMElementEvent,
               vsCMElement.vsCMElementClass,
               vsCMElement.vsCMElementInterface,
               vsCMElement.vsCMElementStruct,
               vsCMElement.vsCMElementEnum,
               vsCMElement.vsCMElementDefineStmt,
               vsCMElement.vsCMElementImportStmt,
               vsCMElement.vsCMElementIncludeStmt,
               vsCMElement.vsCMElementModule,
               vsCMElement.vsCMElementOther
           };
           
        foreach (vsCMElement scope in scopes)
        {
            // Catch and ignore all exceptions from CodeModel.
            // CodeElementFromPoint will raise a COM based exception:
            // System.Runtime.InteropServices.COMException 
            // (0x80004005): Unspecified error.
            try
            {
                codeElement = fileCodeModel.CodeElementFromPoint(textPoint, scope);
                if (codeElement != null)
                {
                    break;
                }
            }
            catch
            {
            }
        }
    }
    
    if (codeElement != null)
    {
        this.textBoxMethodName.Text = codeElement.FullName;
        this.textBoxProjectName.Text =
            codeElement.ProjectItem.ContainingProject.UniqueName;
        this.textBoxFileName.Text = codeElement.ProjectItem.Name;
    }
    else
    {
        this.textBoxMethodName.Enabled = true;
        this.textBoxProjectName.Enabled = true;
        this.textBoxFileName.Enabled = true;
    }
    
    this.textBoxCreatedBy.Text = ReviewWindow.TextToTitleCase(Environment.UserName);
    this.toolStripReviewItemSave.Enabled = true;
}

Points of Interest

Using the Add-in

  • Add-in must be loaded from the Visual Studio IDE. To do this, select Add-in Manager from the Tools menu.
  • To initiate a review, click on "Send to Review" button. This will bring up a new mail message window. Fill in the "To" field and send the mail message to the team members.
  • Reviewers can add review items by selecting review item tab. To modify an item, click on the item in the review list and then select review item tab.
  • A review item can contain comments, such as a rejection comment or comments about the fix.
  • Loading a solution from the Visual Studio automatically loads the current review log from SVN. When closing the solution, the updated review log will be saved in the SVN.

Screenshots

The Review List

The review list

Adding a Review Comment

Adding a review comment

Adding a Comment for a Review Comment

Adding a comment for a review commen

History

  • Oct 5 2011 - Version 1.0.0.0 - Initial version
  • Oct 7 2011 - Added screenshots

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)