<rss version="2.0">
  <channel>
    <title>Dennis Forbes on Pragmatic Software Development</title>
    <link>http://www.yafla.com/dforbes/</link>
    <description></description>
    <lastBuildDate>Sun, 20 Jul 2008 23:41:12 GMT</lastBuildDate>
    <language>en-us</language>
		
		<item>
		  <title>As If .NET Wasn't Confusing Enough</title>
		  <link>http://www.yafla.com/dforbes/As_If_NET_Wasnt_Confusing_Enough/</link>
		  <guid>http://www.yafla.com/dforbes/As_If_NET_Wasnt_Confusing_Enough/</guid>
		  <pubDate>Sat, 10 Jun 2006 16:59:31 GMT</pubDate>
		  <description><![CDATA[<a name="a325"></a><p>While it's evident that Microsoft is staffed with a lot of
top-notch people, history has empirically demonstrated that they
have quite a few dregs as well: Just recall how <a href=
"http://www.joelonsoftware.com/articles/fog0000000049.html">disastrously
the whole .NET thing</a> was handled circa-2000.</p>
<p>For those who forgot, suddenly every product (including those
finished or on the verge of being finished) became a part of the
.NET vision, even if they had absolutely no interaction with the
.NET technology stack: Windows Server.NET, Exchange.NET,
Messenger.NET, SQL Server -- all a part of the .NET generation --
just as Microsoft declared everything in the generation before a
part of the DNA vision (I still hear developers talking about
"Microsoft DNA", not really sure what they're talking about).</p>
<p>As a developer who was heavily involved with the betas of what
we call .NET today - a runtime and a framework, and the associated
tools, for building next generation solutions - I really had no
idea what .NET was in Microsoft parlance. Just as <a href=
"http://www.yafla.com/dennisforbes/Defending-ActiveX/Defending-ActiveX.html">
ActiveX</a> got muddled into a meaningless term, .NET was being
hijacked to basically mean "buy whatever is new or coming out
soon".</p>
<p>Eventually that insanity stopped, and .NET collapsed down to a
sortof virtual-machine runtime, a framework, and a set of tools.
.NET 1.0 was one runtime, one framework, and Visual Studio.NET
2002. .NET 1.1 was a new runtime, a new framework, and Visual
Studio.NET 2003. .NET 2.0 was a new runtime, an expanded framework,
and Visual Studio 2005 (note the dropping of .NET on the naming,
given that Visual Studio, as always, also makes non-.NET
applications). There are countless assemblies and extension
libraries available targeting each of them, and of course I can
make libraries tomorrow that target .NET 1.0, .NET 1.1, or .NET
2.0, and it doesn't magically evolve them into .NET 3.0.</p>
<p>Well <a href="http://blogs.msdn.com/somasegar/">it looks like
Microsoft is at it again</a>. They've decided that Vista's
technology platform, WinFX (which will be partially backported), is
<strong>so</strong> great that it can't be just a set of assemblies
or systems that the .NET runtime interacts with. No, it must be
<strong>.NET 3.0</strong>! So now if you have the .NET 2.0 runtime,
the .NET 2.0 Framework, targeting it with Visual Studio 2005, and
you add in the WinFX framework...voila, you have .NET 3.0.</p>
<p>Insanity. Absolute, unbelievable insanity. Perhaps there's some
amazing explanation -- for instance that their April Fools project
ran a little long, and they just got the output out -- but I
suspect it is just more of the same that we saw circa-2000. Some
short-term euphoria over a gonna-be-released-soon project has them
screwing with the terminology yet again.</p>
<p>Already the boards are full of "So....does this mean WinFX comes
with LINQ?" (LINQ is one of the technologies promised for the next
<strong>real</strong> wave of .NET)</p>

]]></description>
		</item>
		
		<item>
		  <title>FxCop &amp; Cyclomatic Complexity</title>
		  <link>http://www.yafla.com/dforbes/FxCop_Cyclomatic_Complexity/</link>
		  <guid>http://www.yafla.com/dforbes/FxCop_Cyclomatic_Complexity/</guid>
		  <pubDate>Thu, 08 Jun 2006 00:24:48 GMT</pubDate>
		  <description><![CDATA[<a name="a323"></a><p>[The static location of this piece can be found at <a href=
"http://www.yafla.com/dennisforbes/FxCop-Cyclomatic-Complexity/FxCop-Cyclomatic-Complexity.html">
this address</a>]</p>
<h4>FxCop As a Code Quality Tool</h4>
<p>For the past while I've been using <a href=
"http://msdn.microsoft.com/vstudio/teamsystem/developer/">Visual
Studio Team Edition for Software Developers</a>, one of its
benefits over the Professional Edition being the inclusion of
static code analysis functionality right in the IDE.</p>
<p>This functionality comes via the <a href=
"http://www.gotdotnet.com/team/fxcop/">FxCop</a> codeset, which is
an excellent --&nbsp;albeit unpolished -- freely available
tool&nbsp;for analyzing the probable code quality of Intermediate
Language assemblies,&nbsp;testing code to ensure compliance with
naming standards, best practices, and highlighting areas of code
that are suspect. While it's less than pleasant&nbsp;starting FxCop
analysis from scratch on long existing project --&nbsp;to be met
with hundreds upon hundreds of error messages --&nbsp;it's a
painless process if you add it to&nbsp;your&nbsp;quality
checks&nbsp;early on.</p>
<p>The standalone FxCop is largely the same as the VSTE version,
and in some ways is superior. For instance that it retains the
ability to actually pass configuration settings to rules, rather
than accepting whatever the defaults for the rule are.</p>
<h4>Cyclomatic Complexity</h4>
<p>One of the few differences between the standalone application
and the VSTE-included version are the addition of several new
maintenance checks in the Team Edition code, one of the most useful
being the <a href=
"http://www.codeproject.com/dotnet/Cyclomatic_Complexity.asp">cyclomatic
complexity</a> checks. Cyclomatic complexity, for those who haven't
come across it before,&nbsp;is often used to roughly gauge the
complexity of a piece of code, to determine likely candidates for
refactoring, and to identify what will likely become a maintenance
problem in the future. Finding the most complex pieces of code
often brings you to the buggiest code as well.</p>
<p>Given that I still use FxCop, both the .NET 1.1 and .NET 2.0
versions (not least because the integrated version offers no
ability to configure settings for rules, instead only allowing you
to wholesale enable or disable. This eliminates the ability to set
thresholds for tests such as the cyclomatic complexity
rules),&nbsp;the lack of consistency between the two
versions&nbsp;was an annoying gap.</p>
<h4>Introducing Cyclomatic Complexity Analysis For FxCop</h4>
<p>So I implemented a simple cyclomatic counting rule for the
standalone FxCop. While in there, I added checks for statement
count (the number of intermediate language "statements", which can
be indicative of overly complex methods), and callout count (e.g.
callouts to other methods, again which can be an indicator of
overly complex/convoluted methods).</p>
<p>As one added benefit, I added the ability to log all of these
metrics to an SQL-capable OleDB destination (e.g. SQL Server,
Access, etc).&nbsp;If you configured an OLEDB connection string,
as&nbsp;detailed below, you can do data analysis after a run to
create pretty reports of the complexity distributions of your
projects, and so on.&nbsp;</p>
<h4>Download Links</h4>
<p><a href=
"http://www.yafla.com/downloads/yaflaRules_NET1.1.zip">yafla FxCop
Rules for .NET 1.1 (e.g. FxCop 1.32)</a><br />
<a href=
"http://www.yafla.com/downloads/yaflaRules_NET2.0.zip">yafla FxCop
Rules for .NET 2.0 (e.g. FxCop 1.35)</a></p>
<h4>Caveats</h4>
<p>Like any tool of this type, there is only a moderate correlation
between the metrics measured and actual code quality or
maintainability: It is entirely possible that the optimal
implementation is a highly-complex, lengthy method. This tool only
provides guidance, helping to determine which code should get a
complexity analysis, however from there experience and good
judgement have to be applied to determine if it's really a fault.
If you're using the .NET 2.0 version of FxCop, make use of the
SuppressMessage attribute on methods that are necessarily highly
complex.</p>
<h4>Instructions</h4>
<p>Drop yaflaRules.dll in your FxCop Rules subdirectory (e.g.
<em>C:\\program files\\Microsoft FxCop 1.32\\Rules</em>).</p>
<p>If you want more advanced settings, configure FxCop with your
targets and selected rules and then save the project file. Open the
newly created .FxCop file in an editor (for instance notepad) and
find the <em>&lt;Settings /&gt;</em> element. Expand it to an
opening and closing tag (e.g.
<em>&lt;Settings&gt;&lt;/Settings&gt;</em>), and between it add</p>
<p><em>&lt;Rule
TypeName="MethodComplexity"&gt;&lt;/Rule&gt;</em></p>
<p>Between the Rule element add any of the following entries as
Name attributes of an Entry element (as exampled following) -</p>
<p><strong>Connection String</strong> - an OleDb connection string
determining where it will log metrics. e.g.
<em>Provider=SQLNCLI;Server=(local);Database=Analysis;Trusted_Connection=yes;</em><br />

<strong>Target Table</strong>&nbsp;- The target table for metric
logging. Default -
<em>MethodComplexity<br /></em><strong>Cyclomatic Critical
Error</strong><em>&nbsp;-</em> Level at which a critical error is
triggered. Default - 60<br />
<strong>Cyclomatic Error</strong> - Level at which an error is
triggered. Default - 50<br />
<strong>Cyclomatic Critical Warning</strong> - Level at which a
critical warning is triggered. Default - 45<br />
<strong>Cyclomatic Warning</strong> - Level at which a warning is
triggered. Default - 40<br />
<strong>Cyclomatic Information</strong> - Level at which an
infromation event is triggered. Default - 20<br />
<strong>Cyclomatic Recommended</strong> - Recommended level.
Default - 20<br />
<strong>Statements Critical Error</strong> - Statement count at
which a critical error is triggered. Default - 500<br />
<strong>Statements Error</strong> - Statement count at which an
error is triggered. Default - 350<br />
<strong>Statements Critical Warning</strong> - Statement count at
which a critical warning is triggered. Default - 250<br />
<strong>Statements Warning</strong> - Statement count at which a
warning is triggered. Default - 200<br />
<strong>Statements Information</strong> - Statement count at which
an information event is triggered. Default - 150<br />
<strong>Statements Recommended</strong> - Recommended maximum
statement count per method. Default - 100<br />
<strong>Callouts Critical Error</strong> - Callout count at which a
critical error is triggered. Default - 100<br />
<strong>Callouts Error</strong> - Callout count at which an error
is triggered. Default - 75<br />
<strong>Callouts Critical Warning</strong> - Callout count at which
a critical warning is triggered. Default - 50<br />
<strong>Callouts Warning</strong> - Callout count at which a
warning is triggered. Default - 40<br />
<strong>Callouts Information</strong> - Callout count at which an
information event is triggered. Default - 30<br />
<strong>Callouts Recommended</strong> - Recommended maximum callout
count per method. Default - 30</p>
<p>For instance, you might end up with&nbsp;a
<em>&lt;Settings&gt;</em> element that looks like the
following:</p>
<p><em>&lt;Settings&gt;&lt;Rule
TypeName="MethodComplexity"&gt;&lt;Entry Name="Connection
String"&gt;Provider=SQLNCLI;Server=(local);Database=Analysis;Trusted_Connection=yes;&lt;/Entry&gt;&lt;Entry
Name="Callouts Warning"&gt;100&lt;/Entry&gt;&lt;Entry
Name="Cyclomatic Critical
Warning"&gt;500&lt;/Entry&gt;&lt;/Rule&gt;&lt;/Settings&gt;</em></p>
<p>If you opt to take advantage of metrics logging, the destination
table (which will be default will be <em>MethodComplexity</em>,
unless overridden with the <em>Target Table</em> name entry)
requires the following columns:</p>
<p><strong>ContainingType</strong> - text (e.g.
nvarchar(255))<br />
<strong>MethodName</strong> - text (e.g. nvarchar(255))<br />
<strong>Cyclomatic</strong> - int<br />
<strong>Statements</strong> - int<br />
<strong>Callouts</strong> - int<br />
<br />
e.g.<br />
<em>CREATE TABLE [dbo].[MethodComplexity](<br />
&nbsp;[ContainingType] [nvarchar](255) COLLATE
SQL_Latin1_General_CP1_CI_AS NOT NULL,<br />
&nbsp;[MethodName] [nvarchar](255) COLLATE
SQL_Latin1_General_CP1_CI_AS NOT NULL,<br />
&nbsp;[Cyclomatic] [int] NOT NULL,<br />
&nbsp;[Statements] [int] NOT NULL,<br />
&nbsp;[Callouts] [int] NOT NULL<br />
) ON [PRIMARY]</em><br />
<br />
Hopefully someone finds this interesting. It scratched my itch.</p>

]]></description>
		</item>
		
  </channel>
</rss>