2D Head with a clock as an eyeball.
 Wednesday, July 11, 2007

I often get to play the maintenance role in my coding life, and I actually enjoy it, as I get to see how others tackle certain problems. I also like to challenge myself by fixing bugs with the smallest footprint possible. In doing so, I find a lot of common things that bring down the 'maintainability' of a class. I thought I'd share some pain that I encountered today.

Designer Death

All too often I find code that roughly translates to this example:

internal class MyForm : System.Windows.Forms.Form

   MyClass _myClass; 

   public MyForm() 
   { 

      _myClass = new MyClass(); 
      _myClass.MyPropertyChanged += DodgySideEffectEventDrivenCode; 
      _myClass.MyProperty = new object(); 
   } 

   internal void DodgySideEffectEventDrivenCode(Object sender, EventArgs e) 
   { 
      //Lets do something that requires, ooh I dunno....SQL access 
   }
}

I won't go into all the other reasons why this could be seen as bad code, but for the purpose of the example, changing DodgySideEffectEventDrivenCode to look like this can save a whole lotta WSOD's…

internal void DodgySideEffectEventDrivenCode(Object sender, EventArgs e) 

   if (this.DesignMode) return
   //Lets do something that requires SQL access, but only if we aren't in design mode
}

Poor Private Properties

The following is an example of a useless property. There are precious few situations where this would be beneficial to a class.

private static CultureInfo CC

   get { return CultureInfo.CurrentCulture; }
}

Why not use a private readonly field? While I admit there is the odd place where you might insist on a private readonly property, it is the exception rather than the rule. Now, I know Properties look cooler from the Intellisense dropdown, but c'mon, surely this is saving you some time:

private readonly static CultureInfo CC = CultureInfo.CurrentCulture;

Personally, I think the proof is in the IL pudding…

.field private static initonly class [mscorlib]System.Globalization.CultureInfo CC

Compare that to the IL of a readonly property get method:

.method private hidebysig specialname instance class [mscorlib]System.Globalization.CultureInfo get_CC() cil managed
{
    .maxstack 1
    .locals init (
        [0] class [mscorlib]System.Globalization.CultureInfo CS$1$0000)
    L_0000: nop
    L_0001: call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_CurrentCulture()
    L_0006: stloc.0
    L_0007: br.s L_0009
    L_0009: ldloc.0
    L_000a: ret
}

Boolean Badness or Enumerate Early

Sometimes coding isn't enough; sometimes you need to express your intent explicitly. Take the following function declaration which clearly does not:

internal void SetUIState(bool value)

and its usage:

SetUIState(true);

Can you tell how this function will work? Personally I like comments and documentation – and they would help, but self documenting code is worth a page of English documentation. For example:

internal enum UIState

   enabled, 
   disabled,
}

internal void SetUIState(UIState state)

Combined with a decent IDE, the usage and effect becomes apparent:

SetUIState(UIState.enabled);

An even simpler approach would be to just name the function to imply the usage of the state parameter in the first place. I.E

    EnableUI(true);

Personal choice comes into this a lot, but I think we can all agree that it's all about taking care with naming.

On that….

Unchanged UI

If I ever see another TextBox control named 'TextBox1' I'm going to have to hurt somebody. Seriously though, if you have labels and other miscellaneous controls laying about that you don't need to name because you never reference them in code, and you are using VS 2005 or greater then consider the following approach:

  • Use your control key and select the lot of them.
  • Move over to the properties window and set the GenerateMember property to false.

This will keep the controls initialization local to the InitializeComponents routine, thus reducing the clutter in Intellisense and other areas in the IDE quite significantly.

For the rest of your controls and objects, pick a naming convention, and stick to it like glue.


Filed under:  |  | 
 Saturday, July 07, 2007

  Well, I got through most of Saturdays presentations, unfortunately I had to miss the final two on Microsoft CRM and Expression Designer respectively. However the talks I did manage to attend were very useful, and overall I am pleased by the level of discussion at the very first Code Camp SA.

The presentations for the 07/07/07 included the following:Peter Griffith from ADNUG, master of ceremonies for CCSA

The highlight for me today was definitely Mitch Denny's insight into surviving the transition to using TFS for real world development. He had some excellent advice on how to virtualize your TFS server and build servers, how to get continuous integration going, and even some insight into how Readify tackled some of CI's issues in TFS (namely check in monitoring, build quality transition control and build cleanup).

Dr. Michael Baker presented some thought provoking examples on how to start implementing Programming By Contract techniques in your applications, although I have to admit that I thought the presentation would go in a completely different direction. I guess I should have known, but I was expecting to hear about technologies like Thinktecture's Web Services Contract First and associated methodologies.

Dave Glover in his typical, upbeat and enthralling style delivered an excellent introduction to Silverlight, Expression blend and Popfly. After seeing all this I just want to get going with Popfly on something like Microsoft Surface and start feeling the minority report goodness. Very exciting for the mash up scene.

I do owe an apology to Allan Baird et al, from the IT faculty of UniSA, I have had some less than stellar remarks regarding a university education in IT, however it seems that things are starting to look up with the likes of Allan at the steer. He informed the group of a commitment to start teaching Microsoft .NET technologies in core subjects in 2009 and I think this is an excellent step forward for our local IT education prospects in Adelaide. It also appears they are making great efforts to redress the imbalance of female personell in our industry. Not only that, but they are attempting to attract younger crowd to the IT scene in general.

All in all, it was a fun yet instructive day, good to catch up with some previous acquaintances from Code Camp Oz and to meet new people. Thankyou so much to UniSA, ADNUG and the Goodwood 3rd Scout group for putting on a great set of presentations. I'm sure tomorrow will be equally as good.

* sorry Jeff, couldn't get a decent Google fix on you!


Filed under:  |  | 
 Friday, July 06, 2007

Inspired by this recent post about types of programmers, I found myself asking this question:

If you could have databases of information uploaded to your brain, which three would you pick?

I think I'd like to have Google Maps, MSDN and Wikipedia.


Filed under:  | 
 Tuesday, July 03, 2007

Jason recently wrote about ‘building your own’ Vs ‘buying a prebuilt’ PC.

Hot custom 67 by Don Borth.

"I have stopped operating my personal business and now I pay retail for all my hardware instead of going to wholesalers. I have also stopped building my own PCs and my last three purchases have been big name, off the shelf computers. It just isn't worth my time anymore to save a few bucks wherever I can."

I suppose there is a damn good reason why the big names in PC building became big in the first place: They take the pain out of buying and owning a PC. As a fellow system builder from eons ago, I found that two things drove me away from doing it on a grand scale. Firstly, you can’t compete against the 24 hour after sales support of the bigger manufacturers. Secondly, as Jason points out, you are inevitably forced to mix business with friends. I’ve got to admit that it was mainly the former that made it hard, the latter added insult to injury. Because I have chosen not to make a career out of supporting hardware, it is only natural for me to tell friends and family to go and see somebody who is more equipped to deal with their computing needs. I simply am not a hardware support specialist. The story changes dramatically if they would like some advice regarding software decisions (and so does the quote

It’s clear that recommending your friends to go and pick up a cheap PC from Joe’s electronic emporium is tantamount to ending a friendship, but even if Jeff & Scott started building PC’s fulltime for a living I’d probably still build my own.

I still build my own PC's because I'm prepared to take the time to research the combinations (which isn’t all that much) and I'm also prepared to provide myself with the '24 hour after sales support'. If I have a warranty issue, I’m prepared to wait a little longer to get my new part; I have more than one PC anyway. The benefit is that I get to spend more on the areas of the PC that interest me and choose from the widest set of options available. The potential savings, I feel, are a small bonus, perhaps enough to cover my time doing a bit of research on a weekend.

Perhaps the omega geek driven sense of pride of owning my very own DIY desktop scorcher has plunged me into the depths of insanity, but I have come to the conclusion that you can build your own cheap PC and keep it a secret from your friends.


Filed under:
 Friday, June 29, 2007

The topic is well beaten, and often gets revisited. Jeff Atwood & Scott Hanselman have both posted on the issue of learning and programming. It's a big issue because it is the heart of why there are so many people out there who think they can program, but clearly can't. For a few years now I've been harbouring a solution that I think could work.

The problem is that most University degrees teach you very little about the craft of programming in the business context. The other issue is that, the great programmers have 10 years experience before they hit 21.

So here is my crazy idea. Instead of hiring wannabe's fresh out of university, with 0 years experience, why not scout the keen and interested talent from high schools and provide 2-3 year apprenticeships to kids who want to get into the programming game ASAP? Sit your newbie alongside your best programmers and let them soak up the goodness. Start practicing paired programming after a while. I think it's the perfect environment to learn, while being a productive member of the team.

Perhaps the real reason why we as an industry find it hard to get good talent is because we expect the rest of the world to nurture it for us. So many other skills based industries have recognized this as the way ahead; the trades, sales, marketing and so forth. They have seen growth in their talent pool, whereas the IT industry seems to be struggling.

Could it work?


Filed under:
 Thursday, June 28, 2007

Depending on who you ask, I am either unfortunate or lucky enough to spend a significant portion of my working life at home, coding by myself. For one to two days out of each week I break away from the team environs and 'go it alone.'

Now I've never really had a problem with the idea, I grew up in a family that was supported by a family business of one. However recent posts by Jeff Atwood et al, have put a slight negative spin on things.

"Working alone is a temptation for many desperate software developers who feel trapped, surrounded by incompetence and mismanagement in the desert of the real. Working alone means complete control over a software project, wielding ultimate power over every decision. But working on a software project all by yourself, instead of being empowering, is paradoxically debilitating. It's a shifting mirage that offers the tantalizing promise of relief, while somehow leaving you thirstier and weaker than you started. "

I must admit to keeping in touch with reality by way of blogs and IM with colleagues, but when I'm at home, I'm the guy. I know the spirit of the comment is intended to strike at the heart of the one man shop, however I can't help but apply these statements to my own situation.

Personally, I think there is a balance to be found in all things. I don't think that the notion of working alone is this black and white. The distinction that needs to be made here is that there is a significant difference to being a one man shop and working by oneself. I find that, given the correct level of discipline, one can achieve more on certain types of work when you are by yourself. Provided you have a good team to return to when you are done.

Trudge work is the best kind of work to do by yourself, those menial tasks that nobody else is really interested in. Office banter and the like can really distract one from the jobs we hate to do, so doing them alone is often more productive. On the other hand, design decisions are best solved as a team.

So where is the balance? I honestly think that having the opportunity to 'knuckle down' on a new feature or a bug list for a few days, and come back to the team for a bit of review, has real merit. I think most open source development is done in this manner.

Thoughts?


Filed under:
 Tuesday, June 26, 2007

I recently posted on the evils of Microsoft.VisualBasic.MsgBox and have been looking at ways of preventing future problems to do with it. I decided on using static analysis to warn developers that they are using MsgBox rather than MessageBox.Show, so I thought I would share how I went about it.

Writing custom FxCop rules is reasonably well documented, and there are some excellent resources available for the inexperienced and experienced FxCop developer alike:

Of course the rules available in Team System and later versions of FxCop are written in .NET and therefore are very instructive to reflect using something like Reflector. However the process for writing rules can be summed up as such.

   1.   Decide if you are targeting FxCop or VS Team System Code analysis. Because they run different versions, you will have to compile your rules against the appropriate dll's. The good news is that development is largely the same from here on in.

   2.   Create a new class library project in Visual Studio and reference the FxCopSdk.dll and the Microsoft.Cci.dll. You will find these in your FxCop installation directory or in the case of VSTS you will find them in [VSInstallDir]\Team Tools\Static Analysis Tools\FxCop\.

   3.   Write your rule such that it inherits from Microsoft.FxCop.Sdk.Introspection.BaseIntrospectionRule. You may find it useful to create your own base rule class as I did:

      using System;
      using Microsoft.FxCop.Sdk.Introspection;

      namespace Nervoustych.CodeAnalysis
      {
         [CLSCompliant(false)]
         public abstract class BaseStaticAnalysisRule : BaseIntrospectionRule
         {
            protected BaseStaticAnalysisRule(string name) : 
               base(name, "Nervoustych.CodeAnalysis.Rules.Rules"
               typeof(BaseStaticAnalysisRule).Assembly)
            {

            }

            //other base class methods here
         }
      }

    Note the string literal parameter in the constructor; it refers to an embedded XML File resource that describes the rule to the FxCop engine. David Kean has a top example of a base rule class on his site.

   4.   Create the aforementioned XML file and embed it as a resource in your project. The rules document uses a schema called FxCopReport.xsd which is in the Xml directory under the FxCop 1.35 installdir. Here is an example of a Rules.xml file containing one rule.

   <?xml version="1.0" encoding="utf-8" ?> 
   <Rules FriendlyName="Nervoustych Rules"> 
      <Rule TypeName="DoNotUseMsgBox" Category="Nervoustych.Design" CheckId="NT0001"> 
         <Name>Full name of rule</Name
         <Description>Rule description</Description
         <Resolution Name="DoNotUseMsgBox">Resolution Description</Resolution
         <FixCategories>NonBreaking</FixCategories>
         <MessageLevel Certainty="99">Warning</MessageLevel
         <Email></Email
         <Url></Url
         <Owner></Owner
      
</Rule
   </Rules>

   5.   Write the rule. In my rule I wanted to warn developers of uses of MsgBox, so I needed to check any method calls for MsgBox:

   using System;
   using Microsoft.Cci; 
   using Microsoft.FxCop.Sdk; 
   using Microsoft.FxCop.Sdk.Introspection; 

   namespace Nervoustych.CodeAnalysis.Rules 
   { 
      class DoNotUseMsgBox : BaseStaticAnalysisRule 
      { 
         public DoNotUseMsgBox() : base("DoNotUseMsgBox") { } 
         public override ProblemCollection Check(Member member) 
         { 
            Method lMethod = member as Method; 
            if (lMethod == null) return base.Check(member); 
            foreach (Instruction i in lMethod.Instructions) 
            { 
               if (IsMethodCall(i) 
                  && ((Method)i.Value).FullName.Contains("Microsoft.VisualBasic.MsgBox")) 
               { 
                  Problems.Add(new Problem(GetNamedResolution("DoNotUseMsgBox"),
                     i.SourceContext)); 
               } 
            } 
            return Problems; 
         } 

         private static bool IsMethodCall(Instruction instruction) 
         { 
            if (instruction == null
               throw new ArgumentNullException("instruction"); 
            switch (instruction.OpCode) 
            { 
               case OpCode.Callvirt: 
               case OpCode.Call: 
               case OpCode.Calli: 
                  return true
               default
                  return false
            } 
         } 
      } 
   }

As you can see the override to the Check method cycles through each instruction in a method and checks its operation code, to confirm if it's a method call to Microsoft.VisualBasic. MsgBox or not. If it is, then a problem is added to the collection using BaseIntrospectionRule.GetNamedResolution. If anyone could let me know a better way to do this so that I don't have to use a string literal, I would be forever grateful.

   6.   Build your rules project and copy the resultant assembly to either [VSInstallDir]\Team Tools\Static Analysis Tools\FxCop\Rules or [FxCopInstallDir]\Rules depending on your target platform. FxCop will pick up rule assemblies from this directory. At this point you are ready to start using your custom rule against target assembliles using either the FxCop command line, GUI or VSTS code analysis.

   7.   Didn't quite work? If you need to debug your rule, then you will probably want to read this.

    All in all, it's not really that hard, the worst part is learning your way around the undocumented introspection engine. However reflecting the existing rules really helps, and there is a thriving community of mentors to reach out to if the going gets tough. Happy rule making.


    Filed under:  |  | 

    The evidence is clear….running as administrator is dangerous to your sanity. For starters it's addictive, and an entire industry has been generated from this addiction.

    As far as I can tell there are a few reasons why most Windows users insist on running as an administrator.

    • I want to install 'stuff'.
    • I need to move files around in the root directory.
    • My favourite software informs me I have to run as Administrator in order to use it.
    • I don't care.

    If you have any other reasons why you absolutely have to run as an administrator all day long, 7 days a week, I'd be happy to hear it. I think these reasons are the sign of a misinformed user.

    The real issue is that the IT industry has preferred to sell band aid solutions (i.e. antivirus software) rather than educating our customers properly. It's our own fault, a hell of our own design, and its time to demand better. There is a good reason why Linux and Mac have few issues in this department, and it's not because virus writers don't care enough to write viruses for those platforms. It's because the Linux based platforms make themselves hard targets. Vista dropped the ball, and should have made limited accounts the standard. UAC often gets turned off by users who hate message boxes.

    It's really quite simple; if the software you want demands to run as an Administrator at all times after installation, choose different software. Good software won't make such demands on the average user and just simply work. Microsoft has software certifications that demand this of 3rd party vendors, so encourage users to look out for it.

    I want to install 'stuff'

    Sure, after deciding that the latest toolbar from SuperHappy Technologies Inc. is the right toolbar for you, you want to install it. When you're done installing it for all users, create yourself a standard account and log into it. Even better, resist the temptation to install miscellaneous things in the first place. I know it's like collecting handbags or shoes, but you really don't need them. Investigate your installs, a quick Google will often tell you if the SuperHappy Toolbar is in fact ad ware. You don't need to install it to find out.

    I need to move files around in the root directory

    You do? Are you sure? Are you certain that MyResume.docx is better off in C:\Program Files\Resumes\ rather than MyDocs\Resumes\? OK, then go right ahead and log into your administrator account, and when you're done, log back into your standard account. Even better, avoid the temptation to have a 'DIY' file system structure. Make your home directory your castle, and save yourself a world of pain trying to remember which of the 5 resumes directories you created contains your current one. You will also save yourself time when you hit the file system with a search if you can restrict it to a total search area of a few gigs instead of a few hundred.

    My favourite software informs me I have to run as Administrator in order to use it

    Installation is one thing, but if that new game you bought demands to be an Administrator the whole time you are playing then get a different game. It is poorly designed. Really, software needs a damn good reason to run as an admin all the time. It just so happens that programs that demand that they do are also the prime target of virus writers. That naïve, innocent software you've installed can and often will be twisted to the whim of the h4x0rs.

    I don't care

    Too hard? Don't care? Well, you can have the 2396% hard drive performance hit that Norton's Anti Virus will provide you while cleaning up after your spy ware installs. Not to mention the $100 a year subscription for updates, and the bandwidth to download them. I prefer to not own anti virus software, and reap the benefits. When you get right down to it, the nastiest of viruses, will eat AV software alive anyway. The best antivirus program is your brain, and through care and research you can live a virus free life.

    Average users can get away with basic anti virus software that is scheduled to run overnight provided they don't browse the internet and read their emails as an administrator. They can safely turn off the auto protection features, which is the main culprit when it comes to performance decrease.

    Just remember the old adage: a little bit of pain today instead of a whole world of pain tomorrow.


    Filed under:
     Thursday, June 21, 2007

    Well, I bumped into an interesting build error this afternoon, one I hadn't seen before:

    Could not find file 'Microsoft.Windows.CommonLanguageRuntime version=2.0.50727.0'

    For reasons I shan't go into here I write production code in VB .NET, however for unit tests I write in C#. This obviously results in mixed language solutions. The error occurs when I reference a VB windows app project in my C# test project using a project reference. This windows project is also published via ClickOnce. According to this knowledge base article the solution is quite simple: use a file reference. Obviously, as I found out, this issue is not restricted to VB projects referencing VB projects; C# projects that reference VB projects are at risk too.

    The word out on the street is that you can also work around this by turning off ClickOnce security settings on the project being referenced, which wasn't an option for me. It's important to note that this issue is not intended behaviour, and we can expect a fix in the next version of Visual Studio, codename Orcas.

    I'll admit that project references can be problematic, although for the most part they work well at my workplace, but be wary if you are project referencing ClickOnce apps, and don't think you are completely immune if you use C# either.


    Filed under:  | 

    This may not be news to some of you, and for you I apologize. For the rest, please avoid using MsgBox in VB .NET projects, and use MessageBox.Show instead.

    MsgBox is a wrapper around the MessageBox.Show method and is meant for backwards compatibility with older VB projects. It should be left for those who really can't do without it.

    A common misuse for message boxes is debugging code, and most people have invariably found the following code snippet lazing about in production code from time to time:

       Try
          'Some error prone code
       Catch ex as SomeException
          MsgBox(ex)
       End Try

    The problem with this 'debugging' code is that in certain circumstances it will cause bugs of its own. Beware of MsgBox throwing exceptions. I'm not referring to just the documented InvalidOperationExceptions either. If the exception does something interesting in its overload of ToString, or if the MsgBox function fails when determining the title of the message box then anything from StackOverFlowExceptions to OutOfMemoryExceptions can occur.

    But wait…..there's more, another issue is localisation. If you are using FxCop and have turned on System.Globalization, any call to MessageBox.Show must specify the RTL nature of the box to be shown. The problem with MsgBox is that while it does some fancy work to determine the title, it doesn't bother determining the RTL nature of the parent window. The CA rule doesn't appear to have been written to take calls to MsgBox into consideration. In short, calls to MsgBox break the Globalisation rule CA1300.


    Filed under:  |  |  | 

    In my previous post I described how using some readily available tools and some simple conventions for work item creation can equip yourself with some excellent information about how your team works. In this post I intend to explore some of the custom queries that I have been asked to create in day to day life as a TFS consumer.

    One such request was for a query that will tell you, of all the work items you have delegated to others, which ones are outstanding. To achieve this follow these steps to create a TFS query. Having done that you will want to provide the following filters:

    • Team Project = @Project
    • AND Created By = @Me
    • AND Assigned To <> @Me
    • AND State = Active
    • AND Area Path Under <AreaPath>
    • AND Iteration Path Under <IterationPath>

    By changing the "AND State = Active" to be "AND State <> Active" one could query the completed and closed tasks. Optionally you could filter out Scenarios using the 'Work Item Type' field. Don't forget that team explorer can easily dump into and out of Excel which can be handy if you need an earbashing list. The query options straight out of the box are 'good enough' for most situations, and you don't have to write any code if that's not your thing.

    For those of you wanting a little more than a simple query, e.g. you want parameterisation, I did find that creating your own TFS reports was a reasonably straight forward experience as well. The first thing to do is to create a report model on the TFS warehouse objects (TfsReportDS and TfsOlapReportDS by default). TfsOlapReportDS points to a SQL Analysis Services cube which the standard reports all use. One can spend more than a few hours just looking around in there, so consider yourself warned ;)

    Creating the report model is easy enough, just browse to your TFS Sharepoint portal, and find the link to your Report server web interface (typically http://TFSServerName/Reports) and click on the TfsOlapReportDS of TfsReportDS link (the docs say you should favour the TfsOlapReportDS for reporting). Once there you can hit the generate model button and have it generate a reporting model for you. Then just click the link to report builder and start going nuts. I whipped up a non-parameterised report in under an hour that distilled the check-in history of an Area to look like an activity report, using all the wonderful comments our team had provided on each check-in, as a result of the check in policy.

    A quick TFS Report based on the TFS warehouse.

    As you can see I pulled in the change set details, the number of lines changed. Using a quick function on the max and min check in date would show how long the entire project took at a glance. Obvious improvements to this would be grouping by scenario and iteration. This report was brought to you courtesy of the Code Churn entity, which is useful for more than just this simple activity report. You can use code churn to ascertain the quality of your code as well.

    By using the report designer in Visual Studio, you can start leveraging your SQL skills (of which I have very little) to create more elaborate reports, although I think I shall leave that as an exercise for the reader, rather than going into it here as the principle is largely the same. For further information on using the report services I can highly recommend Bob Meyers SQL Reporting Services blog and a book by Paul Turley, Todd Bryant, James Counihan, Dave DuVarney entitled Professional SQL Server 2005 Reporting Services for those who don't mind reading after a hard days coding.

    In summary, developers often concentrate on making sure that each line they write is well crafted, and that's a good thing, so why not make check in time another opportunity to be efficient and useful instead of an inconvenience? There are benefits for developers and project leaders alike, and the key to finding those benefits is by having good data collected at check in time. The analysis tools provided by TFS are powerful enough to satisfy most needs, and if a SQL neophyte like me can whip up a semi-useful report in an hour, imagine what a SQL Jedi could achieve?


    © Copyright 2009 Jim Burger