Feeds I Follow

For those that are interested here are some of the RSS feeds for the blogs that I follow:

  • Channel 9
    Channel 9 is the MSDN video website for all things dev related.
  • dotnet.org.za
    Not a create site and most of the blog just rehash posts from other blogs but once in a while it has something useful.
  • Eric Lippert’s Fabulous Adventures In Coding
    This is a blog I love, this guy works on the .Net Framework and posts some awesome goodies. If you want to be a good dev you should understand the framework’s internals and this blog will help with that.
  • InfoQ (go to the site to create a custom feed)
    A lot of the stuff on here is high level, you won’t find many coding examples etc. But it has some great posts and the range of articles is very broad.
  • Microsoft StyleCop
    This is just so that I know when StyleCop is updated.
  • Mike Taulty’s Blog
    This blog pretty much focuses on SilverLight and Mike Taulty has a number of webcasts on SilverLight if you need to get going with it.
  • Microsoft Architecture Center
    Just as the name says, Architecture related articles, some interesting, some boring.
  • Mythical Man Moth
    A blog I discovered by another South African, I haven’t gone through all his posts yet but there are some interesting ones.
  • rohland.co.za
    Another South African blog I discovered just a few days ago, I’m still going through the posts.

Then some blogs by various developers, I’m not going to comment on them, I’m sure you probably know most of these blogs already:

If you’re frustrated and need a good laugh plug into this feed ;)
ICanHasCheezburger

How to split the web.config into mutliple files

If you’ve ever experienced any pain from having to merge your web.config changes with the web.config in the live environment, or accidentially overwritten the live web.config file this may be a solution for you. You can specify that certain sections of your web.config reside in a seperate file. So you could have a ConnectionStrings.config file containing your connection strings (for the specific environment) and a web.config file that is common across all environments.

To do this you simply add the attribute configSource=”ConnectionStrings.config” to the XML node you want to replace with a file, and then in the file you’ve referenced you simply place the XML that would normally have been in your web.config file. This will allow you do deploy the web.config to different environments without overriding environment specific settings.

Example, in the web.config:

<connectionStrings configSource="ConnectionStrings.config" />

Then in ConnectionStrings.config:

<connectionStrings>
    <add name="ConnectionString1" connectionString="server=localhost; Integrated Security=True; Database=Database1;" providerName="System.Data.SqlClient" />
    <add name="ConnectionString2" connectionString="server=localhost; Integrated Security=True; Database=Database2;" providerName="System.Data.SqlClient" />
</connectionStrings>

Easy as that :)

Install CruiseControl.NET with Subversion

There are a number of blog posts online describing how to configure Cruise Control .NET with SubVersion, none of them worked for me when I followed them, I had to tweak the desribed steps a little. Below are the steps I followed to install Cruise Control .NET with Subversion.

Required Software

Setup

  • Make sure all of the required software is installed.
  • Create the folder _Projects and bind it to the Subversion repository and perform an update.
  • Modify the PATH environment variable to include the path to the folder
    C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE

    • Control Panel
    • System
    • Advanced Tab
    • Environment Variables
  • Check that the virtual directory http://localhost/ccnet exists, if not then create it and point it to the folder C:\Program Files\CruiseControl.NET\WebDashboard
  • Check that the service Cruise Control .NET Service is installed and running.

Cruise Control .NET Configuration

  • Open the file C:\Program Files\CruiseControl.NET\Server\ccnet.config in a text editor. This file contains the settings for the different projects that will be monitored, the basic structure is as follows:
    <project>
        <workingDirectory />
        <triggers />
        <sourcecontrol />
        <tasks />
    </project>
    
  • Project Node: The project node just requires an attribute name with the name of the project.
    <project name="YourProject"></project>
    
  • WorkingDirectory Node: The workingDirectory node is the path to the folder where the project resides.
    <workingDirectory>
        D:\_Projects\trunk\YourProject
    </workingDirectory>
    
  • Triggers Node: The triggers node simply specifies the interval Cruise Control .NET will use to poll the Subversion repository for committed files.
    <triggers>
        <intervalTrigger seconds="60" />
    </triggers>
    
  • SourceControl Node: The sourceControl node has the settings related to getting the source from Subversion.
    • The executable node is the path to the Subversion Console Client.
    • The workingDirectory node is the path to the folder where code from Subversion will be saved.
    • The trunkUrl node is the path to the project source in Subversion.
    • The autoGetSource node can always be set to true.
    • The username and password nodes are the username and password to connect to Subversion with.
    <sourcecontrol type="svn">
        <executable>
            C:\Program Files\SlikSvn\bin\svn.exe
        </executable>
        <workingDirectory>
            D:\_Projects\trunk\YourProject
        </workingDirectory>
        <trunkUrl>
    
    http://localhost:8080/svn/Repository/trunk/YourProject
    
        </trunkUrl>
        <autoGetSource>true</autoGetSource>
        <username>david.turvey</username>
        <password></password>
    </sourcecontrol>
    
  • Tasks Node: The tasks node has a node msbuild that tells Cruise Control .NET to use msbuild.exe to build the project/solution along with all the settings needed.
    • The executable node is the path to MSBuild.exe
    • The workingDirectory node is the path to the folder containing the project/solution.
    • The projectFile node is the filename of the project/solution file.
    • The buildArgs node contains the arguments to pass to MSBuild.
    • The timeout node contains a value in seconds for the timeout of the build.
    • The logger node is the path to ThoughtWorks.CruiseControl.MsBuild.dll
    <tasks>
      <msbuild>
        <executable>
            C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe
        </executable>
        <workingDirectory>
            D:\_Projects\trunk\YourProject
        </workingDirectory>
        <projectFile>YourProject.csproj</projectFile>
        <buildArgs>
            /noconsolelogger /p:Configuration=Debug
        </buildArgs>
        <targets></targets>
        <timeout>300</timeout>
        <logger>
            C:\Program Files\CruiseControl.NET\webdashboard
            \bin\ThoughtWorks.CruiseControl.MsBuild.dll
        </logger>
      </msbuild>
    </tasks>
    

If you browse to the Cruise Control .NET dashboard (http://localhost/ccnet) your project should be in the list, probably with a state of unknown, simply click Force Build on the right to check whether your build succeeds or fails. When someone checks in code a triggered build will occur.

Dropping database objects with a schema

This is just an FYI, I’m sure most people know about this but I thought I’d blog about it because I’ve noticed a lot of stored procedures in the database at work that don’t take the schema into account when they drop the stored procedure.

When dropping some object from the database, e.g. a table or stored procedure, the following statement is often used:

IF EXISTS (
        SELECT *
        FROM sysobjects
        WHERE type = 'P' AND name = 'GetAlertGeographies' )
BEGIN
    DROP PROCEDURE [Members].[GetAlertGeographies]
END
GO

Now this might appear ok but it is not; the select statement that is checking the sysobjects table is not taking the schema into account. So this statement could attempt to drop the stored procedure even though it doesn’t exist because a stored procedure with the same name exists in a different schema.

This is the correct statement to use to take schemas into account:

IF EXISTS (
        SELECT TOP 1 NULL
        FROM information_schema.routines
        WHERE specific_name = 'GetAlertGeographies' AND specific_schema = 'Members' )
BEGIN
    DROP PROCEDURE [Members].[GetAlertGeographies]
END
GO

If you want to check for a table just change “routines” to “tables”.

Easily & safely disposing of objects with the C# using statement

As I’m sure everyone knows, you should always dispose of an object that you’ve created once you’re done using it. The most common way of doing this is using a try… finally block, where the object is disposed of in the finally block.
While there is absolutely nothing wrong with this, there is an easier way in C#; and that is to use a using block. Basically all the using block does is call Dispose on the IDisposable interface once the object referenced at the beginning of the using statement is out of scope.

So here’s how you would do it with a try… finally block:

bool isUnique = false;
SqlParameter[] parameters = new SqlParameter[1];
Utilities.Database database = new Utilities.Database();
SqlDataReader dataReader = null;

try
{
    parameters[0] = database.MakeInParam("@FieldName", SqlDbType.VarChar, 50, _name);
    dataReader = database.GetDataReader("Accounts.ExtraDetailsFieldExists", parameters);
    if (!dataReader.HasRows)
    {
        isUnique = true;
    }
}
finally
{
    if (dataReader != null)
    {
        dataReader.Close();
    }
    if (database != null)
    {
        database.Dispose();
    }
}

return isUnique;

And to do the same thing using the C# using block:

bool isUnique = false;

using (Utilities.Database database = new Utilities.Database())
{
    SqlParameter[] parameters = new SqlParameter[1];
    parameters[0] = database.MakeInParam("@FieldName", SqlDbType.VarChar, 50, _name);

    using (SqlDataReader dataReader = database.GetDataReader("Accounts.ExtraDetailsFieldExists", parameters))
    {
        if (!dataReader.HasRows)
        {
            isUnique = true;
        }
    }
}

return isUnique;

Isn’t that far more readable? Far less code and its very clear where the scope of each object ends. Now I hear you shouting what about closing the data reader! Luckily for us the base class of the SqlDataReader closes the data reader when Dispose is called, and the same applies to the SqlConnection class.