Technology with opinion

Tuesday, November 25, 2008

Creating Custom StyleCop Rules in C#

Microsoft has released a new free static code analysis tool called StyleCop.  Named after the similar FxCop, this product is aimed to be more focused for cosmetic code consistency which can increase readability and maintainability.  StyleCop has built-in rules, which you can turn off, many of which are:
  • Ordering of members in a class from most visible to least visible
  • Order of Usings in alphabetical order, with System namespaces on top
  • Proper camel casing and pascal casing
  • Proper whitespace
I like about 3/4 of these rules so I think it's definitely worth considering using, even consider integrating into your automated build process using NAnt, CruiseControl or TFS.  That being said many will likely want to extend these rules to create your own.  Doing so is fairly simple but not documented very well at this time.  I created the following rule to make sure that all instance variables (private & protected class level variables) are prefixed with an underscore.  I realize not everybody follows this convention, but I like it because it's more concise than prefixing your instance variables with 'm_' or 'this' which is often needed to prevent name collisions.

First I created a C# Class assembly project and referenced "Microsoft.StyleCop" and "Microsoft.StyleCop.CSharp".  Next I added the following class, which implements my custom rule:

using Microsoft.StyleCop;
using Microsoft.StyleCop.CSharp;

namespace DotNetExtensions.StyleCop.Rules
{
    /// <summary>
    /// This StyleCop Rule makes sure that instance variables are prefixed with an underscore.
    /// </summary>
    [SourceAnalyzer(typeof(CsParser))]
    public class InstanceVariablesUnderscorePrefix : SourceAnalyzer
    {
        
        public override void AnalyzeDocument(CodeDocument document)
        {
            CsDocument csdocument  = (CsDocument) document;
            if (csdocument.RootElement != null && !csdocument.RootElement.Generated)
                csdocument.WalkDocument(new CodeWalkerElementVisitor<object>(this.VisitElement), null, null);
        }

        private bool VisitElement(CsElement element, CsElement parentElement, object context)
        {
            // Flag a violation if the instance variables are not prefixed with an underscore.
            if (!element.Generated && element.ElementType == ElementType.Field && element.ActualAccess != AccessModifierType.Public && 
                element.ActualAccess != AccessModifierType.Internal && element.Declaration.Name.ToCharArray()[0] != '_')
            {
                AddViolation(element, "InstanceVariablesUnderscorePrefix");
            }
            return true;
        }
    }
}

The VisitElement function handles the main logic for this rule.  First it makes sure that the member isn't Generated code, which you have no control over so no sense in applying rules to.  Secondly it's making sure that the member's visibility isn't Public or Internal.  Finally we make sure that the instance variable starts with an underscore prefix..

Next we need to provide metadata so that StyleCop can categorize and describe our rule.  Add an XML file to your project, then change it's Build Action to 'Embedded Resource'

<?xml version="1.0" encoding="utf-8" ?>
<SourceAnalyzer Name="Extensions">
  <Description>
    These custom rules provide extensions to the ones provided with StyleCop.
  </Description>
  <Rules>
    <Rule Name="InstanceVariablesUnderscorePrefix" CheckId="EX1001">
      <Context>Instance variables should be prefixed by underscore.</Context>
      <Description>Instance variables are easier to distinguish when prefixed with an underscore.</Description>
    </Rule>
  </Rules>
</SourceAnalyzer>

At the root level you are naming the main category for the rules in this file.  Next you describe your suite of rules.  Then in the Rules section you can add all the rules (note: you can use RuleGroup element to further categorize your rules).  Finally you name your rule and give it a unique CheckId.  The CheckId is what you can search for your rule by in the StyleCop Project Settings.  Important: for StyleCop to correlate your class to your metadata your class and xml file need to be named exactly the same.

Finally build your project and drop your new assembly's dll into the StyleCop directory (C:\Program Files\Microsoft StyleCop 4.3).  Now double-click your Settings.StyleCop to see your rule in the list.  It should look something like the following:



Now you can open your solutions/projects in Visual Studio and click Tools -> Run StyleCop and you should see warnings for your new rule.

StyleCop is a nice little accent to any C# project.  I'd like to see Microsoft make the following changes:
  • StyleCop should be OSS (open source software) - why not Microsoft, there really can't be any proprietary business technology in an application that is basically is performing string  parsing
  • StyleCop's documentation needs to be improved - Microsoft provides to help documents for StyleCop, a user manual and an SDK manual.  Both of them lack details and some of the examples simply do not even compile.  For instance the CodeWalkerElementVisitor delegate in a boolean, in their samples they do not even return a boolean value which will not allow their samples to compile.  They do not even document the purpose of this boolean.  Through trial and error I think that if you return a false that it will stop walking (parsing) the document for this rule.
  • Custom rules should be able to be categorized within the existing main ones: Naming Rules, Ordering Rules, etc.
  • Easier to create custom rules by using regex within an XML file.  This would eliminate having to create custom assemblies and classes.
  • Command-line interface should be available for testing or scripting purposes.

Monday, November 10, 2008

Visual Studio Complaints and Moanings

Visual Studio 2008 has become unbearably slow for me, so I've decided to take some measures.  My first steps was going to include removing the features of Visual Studio that I do not currently use.  Upon attempting to add/remove for Visual Studio I received the following error: 

a problem has been encountered while loading the setup components

So as I research this issue, which seems very common, it seems to be a common theme that people who have patched VS.Net 2008 are having trouble running it's setup. One solution has you install Visual Studio SP1, which I proceeded to install only for it to freeze in the middle.

Next I decided I would just remove the existing hotfixes and patches I have installed for Visual Studio 2008 and then try to add/remove programs for VS.Net 2008.  This worked, I proceeded to remove VB, C++ and database environment.

Finally I was able to apply SP1 to VS.Net 2008, which forced me to reboot.

For those looking to speed up VS.Net a little bit you can try the tips from the following site which seemed to slightly improve the responsiveness for me: dotnettipoftheday.org 

Next I went back into VS.Net 2008 setup to remove some components and removed the following: Enterprise Tools, Dotfuscator Community Edition, Tools for Redistributing Applications, Team Developer and Tester Tools, Team Database Edition and Microsoft SQL Server 2005 Express Edition (actually this was already unchecked).

I then went into add/remove programs and removed: Microsoft Visual Studio Web Authoring Component and the header files (option below I think).  Beware of this however because when I did this I was no longer able to select "Add or Remove Features" within VS.Net setup, my guess is I'd have to 'repair' it first.

These are some of the reasons that Java's Eclipse IDE is so widely popular (in and out of the Java community) because it gives you more granular control over your environment, it's plugins and updates.  This is also why many people, including myself, prefer to have our unit testing and build tools to run outside of the environment.

Heres to one day having a robust C# & ASP.Net plugin for Eclipse.

Tuesday, November 04, 2008

Alt.Net Programmer's Toolbox

Below is my toolbox for most projects.  Just an FYI you only really need to download and install Spring.Net since it includes bins for the other NHibernate, Castle, log4net and NUnit, though you will probably want to download NUnit so you can run the nunit gui.
  • Castle Project - provides IoC, DI and MVC frameworks
  • log4net - mature logging framework for .Net
  • MyGeneration - code generation similar to CodeSmith except open source and free
  • NAnt - build program
  • NHibernate - most mature ORM framework for .Net
  • NUnit - most widely used .Net unit testing framework
  • Spring.Net - enterprise ready framework supports ORM, logging, AOP, Caching through IoC
  • TortoiseCVS - access CVS repositories via Windows Explorer.  Nice to have if you want to get latest source from any open source project
  • TortoiseSVN - access SVN repositories via Windows Explorer.  Nice to have if you want to get latest source from any open source project

Monday, July 21, 2008

The State of Affairs at Microsoft

Microsoft is the modern day Roman Empire of technology as they have dominated their sector relentlessly but lately the company has struggled with analysts questioning the companies leadership including Steve Ballmer as their stock nears 52 week lows. Their various products such as the XBOX, Zune and MSN/Live have all failed to make profits and Microsoft is literally hemorrhaging cash. This is not entirely bad so long as you can bring in more cash than you are hemorrhaging as they have been able to do with their highly successful products such as Windows, Office and enterprise software. While Microsoft in the enterprise in not immediately under threat, the other two legs of their company are: Windows & Office.

Tom Reese and Paul Rubillo writes(forbes) "Microsoft Office division numbers were a disappointment. Operating earnings there only grew a disappointing 12% for the period." Of their online division they write "losses for that division doubled to $488 million from $210 million."

Henry Blodget at Yahoo Finance thinks that Microsoft's real problem is Apple as he cites "Apple shipped 1.4 million computers in the US during Q2, representing 8.5% market share and 38% year-over-year growth.Mac shipments grew 9 times faster than the overall U.S. PC market (4.2%) in Q2." "U.S. Mac sales grew by 386,000 computers year-over-year,handily beating No. 2 HP, which sold just 222,000 more computers in Q2 2008." And to his point Microsoft also recently announced that they are expanding their Apple Mac group to the largest size it's ever been, expecting more demand for MS Office on the Mac.

While an Economist Podcast compared Microsoft trying to compete with Google and Facebook akin to "watching your father try to be cool." Additionally InfoWorld reports that Apple is now the 3rd largest PC vendor in the US.

What does this all mean and how does it relate to IT? Well for years Microsoft has been able to cope with struggling products (MS Money, MSN/Live, XBox, Zune) and still pump money into new enterprise products such as BizTalk and Sharepoint for years before any profits. They were able to do all of this partially because of the tremendous amount of money made through Windows and Office.

Microsoft has also not done much to help themselves, years of making enemies in the software industry have started to haunt them. Efforts to push their own standards in many areas have faltered (HD DVD, OpenDocument). They have even abandoned much work they started with standards like BPEL.. Standards such as OpenDocument or even Microsoft's own OpenXML will end up losing them market share. Productivity applications will be using shared and common formats which will let allow transparency across platforms at the same time when cloud computing solutions like Google Enterprise offer their own productivity suite.

In a nutshell the next step in technology is about ubiquity. With cloud computing now becoming a reality with things such as Google Docs, Google Enterprise and Apple's MobileMe it will no longer matter what platform you run on as Windows, Linux, Macs and mobile devices will operate on common standards. Each of these slowly eroding the high market share Microsoft has in the desktop market and eventually in the enterprise.

Microsoft is not about to vanish but a page is being turned in the history of the company. Bill Gates has stepped down and there is much fresh blood in Microsoft with new perspectives. Don't expect Apple to become the next Microsoft, as I don't think Job's wants Apple to be the next Microsoft. Microsoft's monopoly may of helped consumers in the way that it allowed technology to saturate our life. However at this time it isn't about accessibility to a computer as computers have become passe. The next move will be towards how easy it is to get what we were looking for in a computer anyway (usability & portability).

As individuals in IT it's our responsibility to lay aside vendor loyalty and assess the situation and requirements. We will have to begin making decisions again as Microsoft has made it a little too easy for us in IT to first use what Microsoft has and later argue that it will ultimately mature. It's our responsibility to take risks to change companies which in turn help change the world. Two things I am certain of that will be part of this future: open source software and standards. The enterprises should begin embracing these solutions more often throwing off the fear of the past.

Monday, July 14, 2008

Programming Mantras

Best practices change over time, but Mantras remain true for decades and should be things to live by.  Not these cannot be circumvented but these generally provide direction in what is good:
  1. Less code is better
  2. Nothing is sacred
  3. No FUD (fear uncertainty & doubt);  i.e. make points or decisions based on facts and number, not by invoking emotion and fear
  4. Make it work, make it right then make it fast
  5. Refactor often
  6. Release and build often
  7. Understand what you are going to do before you do it
  8. Separation of duties is good

Thursday, June 26, 2008

Stored Procedures Followup

As a follow up to my previous post that stored procedures (sprocs) aren't a best practice  (http://scottwhite.blogspot.com/2008/04/stored-procedures-reconsidered.html).  I would go as far as saying that as a general rule for database stored procedures are a bad practice.  In general it's hard for the brain to go from one extreme to the other, so as obvious as this may be for some, it is hard to accept for others.  The basis of my argument is to counter each of the positives of stored procedures followed up with the advantages of not using them.

If you are a believer in sprocs as a general rule then you should still come up with some disadvantages to make an impartial decision.  Early June ('08) I was at TechEd and I reiterated my blog regarding stored procedures to a member of the SQL Server development team at Microsoft.  Afterwards I asked if this was correct in his opinion.  His words: "Yes, I tell people not to use stored procedures."

To which I responded "it would be nice for you to tell people this."

"People are going to do what they are going to do" was his response.  My translation is simple: the opinion of your peers do not necessarily reflect the best practices of the vendor.  Additionally times change, best practices change, performance metrics change and Microsoft doesn't typically speak with solidarity when it comes to best practices or design decision.  i.e. as long as you are running on Microsoft platform with Microsoft language and tools they don't care what you do.

At one point in time it was sufficient for systems to compile into each other's code shared header files but this is no longer acceptable and we require packages or assemblies that are more portable such as a DLL.  You have to accept that change is inevitable in life and prepare yourself for trends that you may be uncomfortable with or unaware of.  I'll close with a comment from the creator of Hibernate.

Stored procedures are essentially a nonrelational view of a relational database ... my view, currently, is that the goal of an object-relational mapping tool should be to map between tables and objects, not between objects and "some other stuff."

Thursday, May 08, 2008

NUnit Best Practices

Programming is not just an art, not just a science, but a discipline.  Part of what we all know we should be doing includes solid unit testing.  Below is my list of best practices, feel free to comment and add others I enjoy feedback.
  1. Create a separate assembly for your test fixtures
    • i.e. don't be lazy and put your test fixtures in the same assembly as the application code)
  2. Create a bin folder per solution and place nunit.framework.dll in there
  3. Each project should copy their binaries to the solution bin folder.  Your Post-Build event should look like this: copy $(TargetFileName) "../../../bin/"
  4. Categorize your test fixtures such as DAO, ETL and BusinessRules.  This will let you test pieces of your application more easily: [Category("ETL")]
  5. Once you have the basic interface of a class written, it is time to write your unit test for it.  Even though it will fail it will at least serve as a place holder to go back to as well as serving as a test for when things are working
  6. Make sure each test is atomic.  Therefore if you are inserting data into a table and you know say CustomerName must be unique, then the second time you run your test it will fail because of uniqueness.  For this reason have your persistence tests be all inclusive, include an insert, update and delete.  Put your delete code into a finally so that it is always executed regardless of if the other tests succeed or not
  7. If you notice all of your test fixtures perform certain setup every time, create a base class for this, let's say each one of your DAO classes will be instantiating a connection and opening it before starting and this connection needs to be closed at the end of testing whether it fails or succeeds
    • Obviously we would never want to handle connection objects in our Unit Tests, this would be bad design, in the real world it may be a stream or nhibernate session that you  are configuring.
[TestFixture]
public class DAOBaseFixture
{
SqlConnection cn;

[SetUp]
public void Init()
{
  cn = new SqlConnection();
  cn.Open("...");
}

[TearDown]
public Cleanup()
{
  cn.Close();
}
}

Now derivatives of this class won't even have to implement the [TestFixture] attribute nor take care of their setup.  They will be free to just take care of their own tests.

public class CustomerDAOTests : DAOBaseFixture
{
[Test]
[Category("DAO")]
public void FindAll()
{...}
}

I still recommend to people writing .Net code to use NUnit.  First it's free and you don't have to own any version of Visual Studio to support it.  Therefore if you have programmers or testers offshore who only have Visual Studio Pro they can still run it.  You don't even need a Visual Studio license to run it.  Finally it's a very mature product and it's semantics are well accepted and somewhat portable from language to language.

Monday, April 21, 2008

Stored Procedures Reconsidered

For longtime Microsoft SQL Server users such as myself, one would ask: What is there to reconsider?  It's long considered to be a best practice in the Microsoft world to at least have 3-4 stored procedures (sprocs) for every table usually an insert, update, delete and a simple select statement.

It may surprise some that people outside of the SQL Server world (Oracle, DB2) do not use sprocs nearly as often and they apply them differently.  I will lay out my argument calling for the end of this 'best practice'.

First let's dissect the main arguments for this best practice, they include the following: performance, security, reusability & separation of duties.

Performance argument surrounds the assumption that stored procedures are precompiled.  However this is not always a benefit SQL Server's own Books Online says:

When SQL Server executes stored procedures, any parameter values used by the procedure when it compiles are included as part of generating the query plan. If these values represent the typical ones with which the procedure is called subsequently, then the stored procedure benefits from the query plan each time it compiles and executes. If not, performance may suffer.

 If you read this you will understand that only the part of the query that does not change is precompiled and if the parameters change performance may suffer.  SQL Server stores execution plans for any query sent to it, therefore there is no advantage in this department.  If any performance difference is negligible.  Also if you are dynamically generating SQL in your sproc and executing it, you will also have no performance advantage.  Sprocs also give developers a container to write cursors which are a bad practice (in SQL Server) since they create temp tables.  Additionally the most common stored procedures are usually the most trivial SQL statements (insert, update, delete).

Security argument is based on two arguments: granular security access & SQL Injection attacks.  The granular security argument is that you don't give users access into the table, you only give them access to execute a stored procedure.  My response to this is so what, the user's still have access to insert.  Really what is the risk (odds) of a user finding out the database security credentials, understanding the database, and issuing a proper sql statement.  Odds are if the user is capable of this then they are capable of executing your sproc.  Furthermore many pieces of your security have to fail you for any of this to happen.  I call this a long shot.

The SQL Injection is actually a misconception based on the fact people commonly issue parameterized queries as opposed to constructing a string.  You can use sprocs and still have SQL Injection vulnerability if you are doing something like this:
cmd.Execute("exec InsertCust 1, 'hello'");

 Reusability argument is only relevant if you don't have proper layers in an application to allow reuse from your app tier or business objects.  Unless you are letting other applications access your database which is generally not recommended.

Separation of duties assumes that the job of your RDBMS is to be a repository for SQL code.  This wasn't it's vision and there's a stronger argument that SQL statements fall more inline with business process and business logic therefore they belong there.  If you implement a good ORM strategy then you don't even have to worry about 'hard coding' SQL into your application.  Furthermore your app tier and business objects are more likely to have unit tests therefore regression testing at the object level is seamless.

The case against stored procedures
Stored procedures are procedural, not object oriented therefore their extensibility for reuse is minimal.  This is why a sproc only architecture is a failed one, it's time consuming for little to no return on your investments.  It's common for people to rewrite an entire sproc purely because the original one did not work exactly for their purpose or they do not understand it.

Monday, March 24, 2008

Spring 2008 Toolkit

Below is my complication of free (and mostly open source) development tools and other applications for Spring of '08: