title: ASP.NET MVC - Code analysis / auditing
body: <p>I believe it would be useful to be able to produce an informal report quantifying several aspects of my ASP.NET MVC project.  The intent is to help me determine where I should be focusing my efforts for testing/refactoring.</p>
  
  <p>Some metrics that might be useful to a developer...</p>
  
  <ul>
  <li>List action methods and the number of unit tests for each</li>
  <li>List action methods and the number of lines of code for each</li>
  <li>List action methods that do not use the Authorize attribute</li>
  </ul>
  
  <p>I can produce a list of controllers/methods using reflection.</p>
  
  <pre><code>var controllers = System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
    .Where(t =&gt; typeof(IController).IsAssignableFrom(t)).ToList();
  
  foreach (var controller in controllers)
  {    
    var methods = controller.GetMethods()
      .Where(m =&gt; m.IsAControllerNotDefinedHere()).ToList();
  
    foreach (var method in methods)
      // do something
  }
  </code></pre>
  
  <p>Unfortunately, I fear that if I continue I might end up dumping alot of time into this and end up with something that is difficult to maintain/reuse.</p>
  
  <p>Does anyone have any suggestions for existing solutions (code snippets, open-source, or commercial) that can help me accomplish this goal?</p>
  
  <p><strong>UPDATE:</strong> 
  I'm still seeking input hoping that there is an affordable (or free) solution out there, but I thought I would share some useful reflection techniques that can be used for this purpose.</p>
  
  <p><strong>GetCustomAttributes</strong></p>
  
  <pre><code>var controllers = ...;
  var controllersWithAuthorizeAttribute = controllers
    .Where(c =&gt; c.GetCustomAttributes(typeof(System.Web.Mvc.AuthorizeAttribute), false).Count() &gt; 0).ToList();
  
  var methods = ...;
  var methodsWithHttpPostAttribute = methods
    .Where(m =&gt; m.GetCustomAttributes(typeof(System.Web.Mvc.HttpPostAttribute), false).Count() &gt; 0).ToList();
  </code></pre>
  
  <p><strong>Unit Test Count</strong></p>
  
  <pre><code>// get all types in your unit test project
  var types = Assembly.GetAssembly(typeof(A.UnitTest.Class)).GetTypes();
  // get the test class specific to the current controller (arbitrary)
  var testClass = types.Where(t =&gt; t.Name == controller.Name + "Tests").SingleOrDefault();
  // get unit tests from that test class (specific to NUnit)
  var unitTests = testClass.GetMethods().Where(m =&gt; m.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), false).Count() &gt; 0);
  // count tests (relying on consistent naming scheme - again arbitrary)
  var num = unitTests.Where(t =&gt; t.Name.StartsWith(...).Count();
  </code></pre>
  
  <p><strong>Amount of Code</strong></p>
  
  <p>I couldn't count lines of code using reflection, but I was able to determine the number of Intermediate Language bytes which allows me to give greater scrutiny to those methods that have a higher number of IL bytes.</p>
  
  <pre><code>var method = ...;
  var numBytes = method.GetMethodBody().GetILAsByteArray().Length;
  </code></pre>
  
  <p>All in all, not even close to perfect.  However, I can get the data I need repeatedly without convincing someone to spend money on a commercial product.</p>