Eponymous Laws Of Software Development

08.22.07

Do you want to sound smart, impress your friends, increase your chances of scoring next time you go out on a night on the town? Take a look at Phil Haack's blog post on 19 Eponymous Laws Of Software Development.

My Favorites are Sturgeon's Revelation Ninety percent of everything is crud (it seems to me to have a duel meaning crud = Create Update and delete or crud = crap) and Hofstadter's Law A task always takes longer than you expect, even when you take into account Hofstadter’s Law.

 

Measuring Time Elapsed in Code

08.21.07

Some times you need to time an algorithm or method when trying to increase performance of an application. There is a quick and easy way to do this using the StopWatch class in System.Diagnostics.

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
TestMethod();
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds.ToString());

C#

Mission Complete: Continuous Integration .Net

06.13.07

I have completed or at least gotten a good start with Continuous Integration. What I have done may not be doctrine but it is what I could find to be the simplest and cleanest way. There are in my opinion 4 main parts you must have in order to achieve CI. First you must have a good repository, second you need to have a development tree setup for your project, then each project needs a build script, and finally you need to setup an automated build server. For more on continuous integration check out Martin Fowlers article and Jay Flowers article.

1. Repository

The repository/version control/source code management, what ever you like to call it is the first thing that needs to be established. There needs to be a common place where your entire source is kept so that your build server can know where to get the latest version (head). I choose Subversion (svn) with TortoiseSVN. I was using visual source safe and I was happy about this, but like my grandpa is happy with dial-up, I had no idea what I was missing. If you are using source safe switch now to Subversion its open source and its free you will not regret it.If you would like to know just about everything a user would need to know about modern repositories go to Eric Sink’s online book: Source Control HOWTO.

2. Creating Development Tree

Basically the Development tree is the folder structure/organization of your project. A good development tree is defined by Mike Roberts as easily inheritable on new environments, requires little maintenance, easily maintained, supports productivity, and is consistent. I tried to follow his guide lines in his article: How to Setup a .NET Development Tree. I am using a refactored patterns project I did earlier for this example. I define the trunk/root folder name to be the same as my visual studio solution. In this folder I have 3 other folders src, lib, and tools.

The src contains all the developer created content need to build the solution. The lib contains all references dlls that are needed for the project and are not built with the solution. The tools folder will house things like NAnt, NUnit, FXCop, and whatever else you need to help build quality software. You can also include a docs folder to contain the documentation. Another good source on development trees is an article on

3. Build Script

To automate my builds I choose NAnt  + NAntContrib. I save the build script in the root of the project with the file name of [projectName].Build and a go.bat that contains one line that calls NAnt with the build script.

@tools\nant\Nant.exe -buildfile:[projectName].build %* > buildOut.txt

 

 The > BuildOut.txt saves the out put of the build result to a text file I found this convenient to view how the build went. My build script should be made in a way that is easily implemented, easy to maintain, and need as little maintenance as possible. I include this as an existing solution item that way it can be edited along with the src.

<?xml version="1.0" encoding="utf-8"?>
<project name ="nant" default ="all">
  <!-- The Build Directory -->    
  <property name="build.dir" value ="build"/>
  <!-- Define Default targets and the order they run -->
  <target name="all" depends="clean, compile, run-unit-tests" description="Compile and Run Tests"/>
  <!-- Start fresh, delete build folder -->
  <target name="clean" description="Delete automated build artifacts">
      <delete dir="${build.dir}" if="${directory::exists(property::get-value('build.dir'))}"/>
  </target>
  <!-- Compile solution with msbuild task(Only Available with NAntCOntrib) 
       if it is 2003 use solution task all build properties should be 
       set up in a new VS Automated Build configuration. -->
  <target name="compile">
  <!-- point msbuild to the solution file with should be at the root of your src folder-->    
    <msbuild project="src\Patterns.sln">
      <property name="Configuration" value="Automated"/>
    </msbuild>
  </target>
  <!-- RunUnit tests -->
  <target name ="run-unit-tests">
  <!-- Creates Nunit Reprot Directory-->
    <mkdir dir="${build.dir}\test-reports"/>
    <exec program="nunit-console.exe" basedir="tools\nunit"
      workingdir="${build.dir}">
      <!-- The dll that contains your test that 
           should now be in the build folder -->
      <arg value="Strategy.Test.dll"/>
      <!-- Location and name of the NUnit test report -->
      <arg value="/xml:test-reports\UnitTests.xml"/>
    </exec>
  </target>
</project>

In side VS I set up a new visual studio build configuration called Automated. Automated is basically a copy of the default configuration Release but I changed the folder it builds to be ..\..\build\.

4. Build Server

The final step is implementing your build server. I have heard of people just using scheduled tasks for this but that doesn’t sound very useful. I wanted the build done when some one commits a change to the repository. For this I used CruiseControl.NET. CruiseControl.NET is an Automated Continuous Integration server, implemented using the Microsoft .NET Framework. It works with majority of the source code management (SCM) tools out there and more importantly it works with subversion. The installation was simple just download and run the MSI but the configuration can be a little difficult because of the flexibility available. To get it running you need to edit the ccnet.config.

<cruisecontrol> 
  <!-- Each Project needs the following setup --> 
  <project name="Patterns"> 
    <!-- The Working folder/checked out 
         folder for the project on the server -->
    <workingDirectory>H:\MyApps\Patterns</workingDirectory> 
    <!-- sourcecontrol setup --> 
    <sourcecontrol type="svn"> 
      <!-- URL to the project in the repository --> 
      <trunkUrl>http://www.myrepos.com/myapps/Patterns/</trunkUrl> 
      <executable>D:\Program Files\Subversion\bin\svn.exe</executable> 
      <!-- The Working folder/checked out 
           folder for the project on the server -->
      <workingDirectory>H:\MyApps\Patterns</workingDirectory> 
    </sourcecontrol> 
    <!--Build task--> 
    <tasks> 
      <nant> 
        <!-- Nant EXE for project --> 
        <executable>H:\MyApps\Patterns\tools\Nant\nant.exe</executable> 
        <!-- where the build file lives --> 
        <baseDirectory>H:\MyApps\Patterns</baseDirectory> 
        <buildArgs></buildArgs> 
        <nologo>false</nologo> 
        <buildFile>Patterns.build</buildFile> 
        <buildTimeoutSeconds>1200</buildTimeoutSeconds> 
      </nant> 
    </tasks> 
    <!-- reporting information --> 
    <publishers>             
      <merge> 
        <files>         
          <!-- Location of Unit test reports --> 
          <file>H:\MyApps\Patterns\Build\test-reports\UnitTests*.xml</file> 
        </files> 
      </merge> 
      <!-- create the log files used by the CruiseControl.NET Web Dashboard --> 
      <xmllogger logDir="D:\Program Files\CruiseControl.NET\server\Patterns\BuildLogs" /> 
      <!--default statistics for capturing during the build process.--> 
      <statistics /> 
    </publishers> 
  </project> 
</cruisecontrol>

After that just edit the project, commit the changes, and watch the dashboard build report.

Getting Started with .Net Development

06.08.07

I am really impressed with the amount of developer support being put out by Microsoft; everything you need to get started is pretty much free. You can download the Express version of Visual Studios and it gives you a majority of its big brothers features which is 300$ IDE, the most notable difference is that the express version is not pluggable. There are different flavors of Visual Studio express, one for windows, web with AJAX, hardware/robotics and game /XNA development.  Although the free IDE is nice and I use visual studio as my primary development tool I am totaly blown away with the amount of resources available for learning. I am not talking about the MSDN Library, most of the time the MSDN documentation just confuses me, but webcast live and On Demand, podcasts and virtual labs are fantastic. There is tons of time worthy information put up here for beginning and advance programmers. It’s the first place I go to when I am trying to learn a new technology. I hear a lot of trash talked about Microsoft everywhere I go but I feel they have the best development support out there.

Mission: Continuous Integration

05.25.07

When I first accepted this mission I was so excited I imagined my self doing a happy dance, it was a Latin dance because maracas are cool. I thought this was going to be great! I am going to have an automated build process that hooks into source control so it will build the latest check in, run unit test, and then give you feed back on how every thing worked out. I was not in the least bit intimidated by the complexity of how all that may be because well all shops should have this, it can’t be any harder than installing Visual Studio, right? After about an hour of research my head exploded.

I have a lot of learning to do but I have found some references that will hopefully lead me in the right direction.

Reference:

How do I learn?

05.08.07

    I was at school the other day talking to a class mate he was admitting to me that some thing big needs to change in his life. He was about to graduate with a BS in Software Engineering and he all ready has his AAS in Software Application Programming, but he still did not have confidence in his abilities as a programmer. This made me think; we started school at the same time with about the same skill level. Why has my skill and confidence in them surpassed his? I believe it has to be because I strive to find and consume knowledge in multiple ways.
    I regularly listen to podcasts and watch webcast. I am also subscribing to multiple blogs from people I believe to be successful and knowledgeable programmers. I always have at least one book that I am reading that is related to the field. I attend classes on programming as well as try to instruct others on techniques through my blog as well as in person. On top of my work, I always have a side project going on that allows me to practice new and interesting technologies. That seems like a lot and it is, but I enjoy it. I guess that is the real answer, you have to enjoy it to be proficient at it.

The One Game to Rule Me.

05.01.07

I feel like a recovering crack addict who fell off the wagon. I have an addiction problem with MMOs, I was stuck on World of Warcraft for about a year I could not stop playing it, it wasn't until my computer had a melt down and I was forced to take a break that I acutely was able to quit the Wow habit. I was clean for almost a year, I focused on school and learning more programming, but I found my self a new drug it is called The Lord of the Rings Online, I am ashamed to say that it is eating my sole all ready. I love Middle-Earth and the amount of lore these guy put into it is amazing, wondering around this immense world really makes you feel like you are adventuring in the same one as Bilbo and Frodo. I am trying my best to limit my fanatic zeal for playing this game but my attempts are weak and you can probly find me online I am on the server Arkenstone, and my name is Grubz hope to see you in game.

Finding your Solution/Discoverability for DotNet Developers.

04.07.07

 

   
I was listening to .Net Rocks today and they where interviewing Dan Appleman on discoverability. I thought when I herd this title it was going to be a show on how to make you application features get noticed, but this show was even better. This show was on how to make your life as a developer easier, easier by tipping you on how to find solutions to your problems that have already been solved. The best tip was on Google custom search this allows you to create your own seach that only searches sites that you specify. Dan Appleman has already done this work for us .Net Developers. He gathered up his favorite reference sites and created the site SearchDotNet. Try it out!


Switching to C# from VB.Net

04.05.07

My current job requires me to jump on the band wagon and start coding in the C# syntax for .Net. For the last year I have been coding in VB.Net and doing all my blog examples in VB.Net and I really started to enjoy that language. The My namespace allowed for quick access to a number of common functions, key words such as AndAlso and OrElse eliminated the need for extra if statements, the background compiler was great finding errors instantly, the VB.Net code is formatted automatically for you (in C# I find my self having to hit ctr+K+D a lot and some times still have to format braces my self), and the lack of {}.[], <>, and () makes the language easy to read.
    My switch to C# was relatively easy I can't quite code as fast as I am able to in VB.Net and I still try to write Dim, forget semicolons, and other little syntax issues like that. I like that C# seems to hide less from you than VB.Net one example is just having the namespace automatically at the top of the page. C# is also less wordy than VB.Net and I can see more of the code that is important to me at one time. Maybe its just because I am new to the language but C# seems to have less ambiguous ways of doing things as well, witch seems to make code from programmer to programmer more consistent. Example of this is casting int from a string in VB you can use Cint(str), Ctype(str,int), Integer.Parse(str), and Val(str). There are a lot of other instances of this in VB.Net I think it has a lot to do with helping the VB 6.0 coders with there transition to .Net.
    All and all it is a refreshing change and I like going back to “C” derived syntax I believe to progress as a programmer you really need to experience in multiple languages.

The Strategy Pattern

04.04.07

    The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. What does this mean?
    From my understanding of the strategy pattern, you are separating the behavior from an object with the use of an interface. The interface defines the family of algorithms and you encapsulate each behavior with a class that implements this interface. With this use of the interface contained in the class you have the ability to reference different behaviors at runtime.
    To better understand this I created a simple app that is a form with a button. When this button is clicked it uses Reflection to load a .dll that contains a class that defines the behavior of the button.



The first thing I did to implement the strategy pattern was to create my interface that defines my family of behaviors/Algorithms.
namespace Patterns.Strategy.PluginInterface
{
    public interface ICrazyBehavior
    {
        void GoCrazy();
    }
}

In order to assign a concrete behavior I created a class that implemented this interface.

using Patterns.Strategy.PluginInterface;
using System.Windows.Forms;
namespace MyUsefullPlugin
{
    class MyUseFullPlugin : ICrazyBehavior
    {
        public void GoCrazy()
        {
            MessageBox.Show("This Plug-in is out of controll");
        }
    }
}


Finally I wrote the class that contains the interface and all other content I needed.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using Patterns.Strategy.PluginInterface;
namespace Patterns.Strategy
{
    public partial class PlugableStrategy : Form
    {
        private List<ICrazyBehavior> _crazyBehavior = new List<ICrazyBehavior>();
        public PlugableStrategy()
        {
            InitializeComponent();
        }
        private void btnGoCrazy_Click(object sender, EventArgs e)
        {
            GetPlugins();
            foreach (ICrazyBehavior thisBehavior in _crazyBehavior)
            {
                thisBehavior.GoCrazy();
            }
        }
        // Messy Reflection stuff
        private void GetPlugins()
        {
            _crazyBehavior.Clear();
            string path = Application.StartupPath + "/Plugins";
            string[] files = Directory.GetFiles(path, "*.dll");
            foreach (string file in files)
            {
                try
                {
                    Assembly asm = Assembly.LoadFrom(file);
                    Type[] types = asm.GetTypes();
                    foreach (Type type in types)
                    {
                        Type[] interfaces = type.GetInterfaces();
                        foreach (Type currentInterface in interfaces)
                        {
                            if (currentInterface.Name == "ICrazyBehavior")
                            {
                                if (currentInterface.Namespace == "Patterns.Strategy.PluginInterface")
                                {
                                    object obj = asm.CreateInstance(type.Namespace + "." + type.Name);
                                    _crazyBehavior.Add((ICrazyBehavior)obj);
                                }
                            }
                        }//interface
                    }//type
                }
                catch (Exception) { }
            }//file
        }
    }
}

So, putting this all together I have my form/class that contains a button when some one clicks this button it calls GetPlugins(). The method GetPlugins() uses Reflection to find any .dlls in the plugins folder that contains the ICrazyBehavior interface with the name space of Patterns.Strategy.PluginInterface. If such thing exists in the folder it creates an instance of this object and adds it to my list of _crazyBehaviors once the list is filled the click event continues, it iterates through the list calling the method GoCrazy().

    Using the strategy pattern allowed me to decouple the context class and its behavior enabling me to implement a very "useful" pluggable application.

The Code:

Patterns.zip (83.64 KB)