• Home
  • Functionality
  • Functions
  • Pricing
  • News
  • Blogs
Download
Login
Skip Navigation LinksBlogs > RainerStropek > Blog
Follow timecockpit on Twitter

Hands-On Labs StyleCop and Code Analysis

By Rainer Stropek in Category:
Wednesday, December 08, 2010

This week I will be one of the speakers at BASTA On Tour in Munich. One of the topics I am going to speak about is the Managed Extensibility Framework (MEF). In this blog post I want to share my slides and summarize the hands-on labs that I am going to go through with the participants.

  • Download Slides (PDF)

Hands-On Lab 1: StyleCop Documentation Rules

Prerequisites:

  • Visual Studio 2010
  • Download and install the latest version of the StyleCop from http://stylecop.codeplex.com/

Lab step by step description:

  • Create a class library project StyleCopDemo.
  • Add the following class to the newly created project:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace styleCopDemo
    {
     public class utils_Bucket<T>
     {
      public utils_Bucket()
      {
      }

      public utils_Bucket(IEnumerable<Tuple<string, T>> data)
      {
       foreach (var item in data) {
        this.data[item.Item1] = item.Item2;
       }
      }

      private Dictionary<string, T> data = new Dictionary<string, T>();

      public T this[string index]
      {
       get
       {
        if (data.ContainsKey(index))
        {
         return data[index];


        }
        else
         return default(T);
       }
      }

      public int GetLength()
      {
       return this.data.Keys.Count;
      }

      private string Dump()
      {
       return this.data.Aggregate<KeyValuePair<string, T>, StringBuilder>(
        new StringBuilder(),
        (agg, item) =>
        {
         if (agg.Length > 0)
         {
          agg.Append(", ");
         }
         agg.AppendFormat("{0}: {1}", item.Key, item.Value.ToString());
         return agg;
        }).ToString();
      }
      public override string ToString()
      {
       return this.Dump();
      }
     }
    }

  • Launch StyleCop Settings (right-click on project, select StyleCop settings).
  • Enable all rules except Spacing Rules / SA1027
  • Build your project and make sure that there are no errors and no warning.
  • Run StyleCop on your project (right-click on project, select Run StyleCop). As you can see StyleCop generated a bunch of warnings.
  • Correct all warnings appropriately.
  • After that your file should look similar to the following implementation:

    //-------------------------------------------------------
    // <copyright file="Bucket.cs" company="Contoso Ltd.">
    //     Copyright (c) Contoso Ltd. All rights reserved.
    // </copyright>
    //-------------------------------------------------------

    namespace StyleCopDemo
    {
     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;

     /// <summary>
     /// Implements a bucket
     /// </summary>
     /// <typeparam name="T">Type of the elements in the bucket</typeparam>
     public class Bucket<T>
     {
      /// <summary>
      /// Internal helper to store data
      /// </summary>
      private Dictionary<string, T> data = new Dictionary<string, T>();

      /// <summary>
      /// Initializes a new instance of the Bucket class.
      /// </summary>
      public Bucket()
      {
      }

      /// <summary>
      /// Initializes a new instance of the Bucket class.
      /// </summary>
      /// <param name="data">The initial data.</param>
      public Bucket(IEnumerable<Tuple<string, T>> data)
      {
       foreach (var item in data)
       {
        this.data[item.Item1] = item.Item2;
       }
      }

      /// <summary>
      /// Gets the element at the specified index.
      /// </summary>
      /// <param name="index">Index of the element to get.</param>
      /// <value>Element at the specified index.</value>
      public T this[string index]
      {
       get
       {
        if (this.data.ContainsKey(index))
        {
         return this.data[index];
        }
        else
        {
         return default(T);
        }
       }
      }

      /// <summary>
      /// Gets the length.
      /// </summary>
      /// <returns>Length of the dictionary</returns>
      public int GetLength()
      {
       return this.data.Keys.Count;
      }

      /// <summary>
      /// Returns a <see cref="System.String"/> that represents this instance.
      /// </summary>
      /// <returns>
      /// A <see cref="System.String"/> that represents this instance.
      /// </returns>
      public override string ToString()
      {
       return this.Dump();
      }

      /// <summary>
      /// Dumps this instance.
      /// </summary>
      /// <returns>String representation of the dictionary</returns>
      private string Dump()
      {
       return this.data.Aggregate<KeyValuePair<string, T>, StringBuilder>(
        new StringBuilder(),
        (agg, item) =>
        {
         if (agg.Length > 0)
         {
          agg.Append(", ");
         }

         agg.AppendFormat("{0}: {1}", item.Key, item.Value.ToString());
         return agg;
        }).ToString();
      }
     }
    }

Hands-On Lab 2: StyleCop Build Integration

Prerequisites:

  • Visual Studio 2010
  • Download and install the latest version of the StyleCop from http://stylecop.codeplex.com/
    • Make sure that you have selected MSBuild integration files when installing StyleCop
  • Complete Hands-On Lab 1 (see above)

Lab step by step description:

  • Open the resulting solution from Hands-On Lab 1 (StyleCopDemo).
  • Unload the StyleCopDemo project (right-click on project in Solution Explorer, select Unload Project).
  • Edit StyleCopDemo project (right-click on project in Solution Explorer, select Edit StyleCopDemo.csproj).
  • Scroll to the end of the file. Find the line <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />.
  • Immediately after that line add the following line:

    <Import Project="$(ProgramFiles)\MSBuild\Microsoft\StyleCop\v4.4\Microsoft.StyleCop.targets" />

  • Reload the StyleCopDemo project (right-click on project in Solution Explorer, select Reload Project).
  • Build your project to see that there are no errors and warnings.
  • Break a StyleCop rule (e.g. remove the documentation of a method).
  • Build your project.
    • StyleCop should have run automatically, you should see an appropriate warning.
  • Unload the StyleCopDemo project (right-click on project in Solution Explorer, select Unload Project).
  • Edit StyleCopDemo project (right-click on project in Solution Explorer, select Edit StyleCopDemo.csproj).
  • Find the first PropertyGroup in the project file and add the following setting:

    <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>

  • Reload the StyleCopDemo project (right-click on project in Solution Explorer, select Reload Project).
  • Build your project.
    • The StyleCop warning should now be an error.
  • Suppress the warning/error using the SuppressMessage attribute:

    [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented",
      Justification = "No time to write documentation...")]
    public class Bucket<T>
    {
      ...
    }

Hands-On Lab 3: Code Analysis

Prerequisites:

  • Visual Studio 2010
  • Complete Hands-On Lab 1 (see above)

Lab step by step description:

  • Add a new class library project to solution from Hands-On Lab 1 (StyleCopDemo).
  • Add the following class to the newly created project:

    namespace CodeAnalysisDemo
    {
     using System;
     using System.Collections.Generic;
     using System.Data.SqlClient;
     using System.IO;

     public interface ISwiftItem<T>
     {
      string ItemName { get; }
      List<T> Values { get; }
     }

     public interface INamedItem
     {
      string ItemName { get; }
     }

     public class SwiftItem<T> : ISwiftItem<T>
     {
      public string ItemName
      {
       get;
       set;
      }

      public List<T> Values
      {
       get;
       set;
      }
     }

     public class SwiftFile
     {
      private Stream underlying_File;
      private string fileName;
      private object header;

      public SwiftFile(string fileName)
      {
       this.underlying_File = new FileStream(fileName, FileMode.Open);
       this.fileName = fileName;
       this.header = new object();
      }

      public List<Tuple<string, object>> Settings
      {
       get;
       set;
      }

      public void AddObject<T>(SwiftItem<T> newObj)
      {
       lock (this.header)
       {
        var header = string.Format("{0}: {1}", newObj.ItemName, newObj.Values.Count);

        foreach (var item in newObj.Values)
        {
         if (item is INamedItem)
         {
          var namedItem = item as INamedItem;

          // do something special with namedItem
         }
        }

        // do something with newObj
       }
      }

      public void CopyFile(string source_file_name)
      {
       using (var reader = new StreamReader(new FileStream(source_file_name, FileMode.Open)))
       {
        // TODO: copy file here
       }
      }

      public void WriteToDatabase(SqlConnection conn, string tenant)
      {
       var cmd = conn.CreateCommand();
       cmd.CommandText = string.Format("INSERT INTO Target ( Tenant, Data ) VALUES ( {0}, @Data )", tenant);
       
       // Build rest of the command and execute it
      }

      public void Close()
      {
       try
       {
        this.underlying_File.Close();
       }
       catch
       {
        Console.WriteLine("Error");
       }
      }
     }
    }

  • Build your project and make sure that there are no error and no warnings.
  • Enable Code Analysis for the project and select rule set Microsoft All Rules.
    • You find the necessary options in the project's property window.
  • Build your project. As you can see code analysis shows you a bunch of warnings.
  • Try to correct all warnings appropriately. If you are not sure what a certain warning means or why it is important check the rule documentation in MSDN: http://msdn.microsoft.com/en-us/library/ee1hzekz.aspx
  • After that your file should look similar to the following implementation:

    using System;

    [assembly: CLSCompliant(true)]

    namespace CodeAnalysisDemo
    {
     using System.Collections.Generic;
     using System.Collections.ObjectModel;
     using System.Data;
     using System.Data.SqlClient;
     using System.Diagnostics.CodeAnalysis;
     using System.IO;

     public interface ISwiftItem<T>
     {
      string ItemName { get; }
      IEnumerable<T> Values { get; }
     }

     public interface INamedItem
     {
      string ItemName { get; }
     }

     public class SwiftItem<T> : ISwiftItem<T>
     {
      public string ItemName
      {
       get;
       set;
      }

      public IEnumerable<T> Values
      {
       get;
       set;
      }
     }

     public class Setting
     {
      public string SettingName { get; set; }
      public object SettingValue { get; set; }
     }

     public class SettingCollection : Collection<Setting>
     {
     }

     public class SwiftFile : IDisposable
     {
      private Stream underlying_File;
      private object header;
      private bool disposed;

      public SwiftFile(string fileName)
      {
       this.underlying_File = new FileStream(fileName, FileMode.Open);
       this.header = new object();
       this.Settings = new SettingCollection();
      }

      public SettingCollection Settings
      {
       get;
       private set;
      }

      public void AddObject<T>(SwiftItem<T> newObj)
      {
       if (newObj != null)
       {
        lock (this.header)
        {
         foreach (var item in newObj.Values)
         {
          var namedItem = item as INamedItem;
          if (namedItem != null)
          {
           // do something special with namedItem
          }
         }

         // do something with newObj
        }
       }
      }

      [SuppressMessage("Microsoft.Performance", "CA1822", Justification = "Will reference 'this' later")]
      public void CopyFile(string sourceFileName)
      {
       var stream = new FileStream(sourceFileName, FileMode.Open);
       StreamReader reader;
       try
       {
        reader = new StreamReader(stream);
       }
       catch
       {
        stream.Dispose();
        throw;
       }

       try
       {
        // do something with reader
       }
       finally
       {
        reader.Dispose();
       }
      }

      [SuppressMessage("Microsoft.Performance", "CA1822", Justification = "Will reference 'this' later")]
      public void WriteToDatabase(SqlConnection conn, string tenant)
      {
       if (conn == null || (conn.State & ConnectionState.Open) == 0)
       {
        throw new ArgumentException("conn must not be null and must be open");
       }

       var cmd = conn.CreateCommand();
       cmd.CommandText = "INSERT INTO Target ( Tenant, Data ) VALUES ( @Tenant, @Data )";
       cmd.Parameters.Add("@Tenant", System.Data.SqlDbType.NVarChar, 100).Value = tenant;

       // Build rest of the command and execute it
      }

      public void Close()
      {
       try
       {
        this.underlying_File.Close();
       }
       catch
       {
        Console.WriteLine("Error");
        throw;
       }
      }

      private void Dispose(bool disposing)
      {
       if (!this.disposed)
       {
        if (disposing)
        {
         this.underlying_File.Dispose();
        }

        disposed = true;
       }
      }

      public void Dispose()
      {
       this.Dispose(true);
       GC.SuppressFinalize(this);
      }

      ~SwiftFile()
      {
       Dispose(false);
      }
     }
    }

  • Facebook
  • Twitter
  • DZone It!
  • Digg It!
  • StumbleUpon
  • Technorati
  • Del.icio.us
  • NewsVine
  • Reddit
  • Blinklist
  • Add diigo bookmark

Comments  6

  • Gracelyn 10 Apr

    QnXDyS Kudos! What a neat way of thinking about it.
  • Tori 10 Apr

    CjYdWl Sounds great to me BWTHDIK
  • ermxtt 12 Apr

    WZq9lQ , [url=http://mjpudasrjlsv.com/]mjpudasrjlsv[/url], [link=http://opmwlgluckqe.com/]opmwlgluckqe[/link], http://piozgxgddntc.com/
  • cpwniurb 12 Apr

    BgRSxJ , [url=http://fccjufnoffbe.com/]fccjufnoffbe[/url], [link=http://jpyxjeukmgos.com/]jpyxjeukmgos[/link], http://rgchhkjpskqw.com/
  • ljmsaz 24 Apr

    RtQiwc , [url=http://wmhirmpztlpu.com/]wmhirmpztlpu[/url], [link=http://bgsacwsuiwig.com/]bgsacwsuiwig[/link], http://evvgetdyfxxb.com/
  • vvzngdb 24 Apr

    a8CzHx , [url=http://aldhrrghaqqs.com/]aldhrrghaqqs[/url], [link=http://mqjvvzbdcunr.com/]mqjvvzbdcunr[/link], http://ceztysnsscnn.com/
Post a comment!
  1. Formatting options
       
     
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
     
     
     
       

Blogger

  • Alexander Huber (1)
  • Karin Huber (3)
  • Philipp Aumayr (10)
  • Rainer Stropek (39)
  • Simon Opelt (5)

Kategorien

  • .NET (7)
  • Azure (4)
  • IronPython (5)
  • Screencasts (12)
  • time cockpit (27)
About Us  |  Legal Notices  | © 2010 software architects gmbh. All rights reserved.