Alan Dean

CTO, Developer, Agile Practitioner

Photograph of Alan Dean

Sunday, February 20, 2011

How to conditionally skip compilation

As I mentioned in my last post, I was having problems getting an MVC web application to play nice with my framework targeting builds. Specifically, my CI server would fall over if I tried to build using Framework 3.5 when the web application was using 4.0 (due to 4.0-specific web.config settings that 3.5 does not recognise). I managed to spend a large portion of the afternoon searching for an answer until I had one of those “eureka” moments. My objective was to simply not build the web application unless the framework was 4.0 (the same would apply to any project that is framework version-specific). I tried putting a conditional on the project element. No Joy. I tried a whole bunch of other things and it was starting to look like I would have to manually configure each project to be built – very nasty, not at all what I want.

My “eureka” moment happened as I was gazing forlornly at a project file. My eye alighted upon an attribute of DefaultTargets="Build" on the project element. Build? I thought… I’ve not seen a target called that. A quick check confirmed my suspicion. The “Build” target is effectively inherited. In a flash I thought I wonder if I can intercept this? I changed the attribute to DefaultTargets="Conditional" and then added the following target and all is well again in Narnia:

<Target Name="Conditional">
<CallTarget Targets="Build" Condition=" '$(TargetFrameworkVersion)' == 'v4.0' " />
</Target>

Framework version targeting with MSBUILD

I faced a question this weekend: how best should I support conditional compilation by framework? The proximate reason for asking this was a need to use BigInteger in the Cavity project in order to be able to support 128-bit base-36 notation with a minimum of fuss. This is a new value type in Framework 4.0 and up until now Framework 3.5 have been the target for Cavity assemblies. As 3.5 is going to be around for a good while yet (heck, there is still plenty of 2.0 in production today) I didn’t want to orphan support for that version. I also didn’t want to add complexity to my build or maintenance activities. This ruled out brute force options such as creating a branch for 3.5 or creating a new solution and project files for one or other of the framework versions.

A search yielded a varied collection of advice. Some was plainly potty but a couple of StackOverflow answers [1] [2] looked promising. Taking the answers and combining a bit of common sense, I put together a quick spike to verify that I had the gist of it. Here is what I learnt:

  1. The best way to control targeting is to use property parameters with a build file. Here is a .bat file to build release versions targeting each major framework version:
    MSBUILD build.xml /p:Configuration=Release /p:TargetFrameworkVersion=v2.0
    MSBUILD build.xml /p:Configuration=Release /p:TargetFrameworkVersion=v3.5
    MSBUILD build.xml /p:Configuration=Release /p:TargetFrameworkVersion=v4.0

  2. You don’t need to do anything in the build.xml or the .sln file for this to work. You do, however, need to do a little work in the .csproj files:
    • First, you need to decide which framework version you want to work with in Visual Studio (typically, this will be the latest version) and configure TargetFrameworkVersion accordingly:

      <TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.0</TargetFrameworkVersion>

    • To make the build output obvious, set the OutputPath to use properties:

      <OutputPath>bin\$(Configuration) $(TargetFrameworkVersion)\</OutputPath>

    • Next, you should set up some conditional property groups:
      <PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v2.0' ">
          <DefineConstants>NET20</DefineConstants>
          <TargetFrameworkVersionNumber>2.0</TargetFrameworkVersionNumber>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v3.5' ">
          <DefineConstants>NET35</DefineConstants>
          <TargetFrameworkVersionNumber>3.5</TargetFrameworkVersionNumber>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">
          <DefineConstants>NET40</DefineConstants>
          <TargetFrameworkVersionNumber>4.0</TargetFrameworkVersionNumber>
      </PropertyGroup>

    • This allows you to configure framework-specific assembly references, such as System.Core and Microsoft.CSharp:

      <Reference Include="System.Core" Condition=" '$(TargetFrameworkVersionNumber)' >= '3.5' " />
      <Reference Include="Microsoft.CSharp" Condition=" '$(TargetFrameworkVersionNumber)' >= '4.0' " />

    • You should now be able to target framework versions in a straightforward manner by running the batch file above.

  3. If you want to conditionally include classes, simply apply a framework condition:
    <Compile Include="Class20.cs" Condition=" '$(TargetFrameworkVersion)' == 'v2.0' " />

  4. I also defined constants above to allow conditional compilation at code level:
    namespace Example
    {
        public sealed class Class1
        {
    #if NET20
            public void Net20()
            {
            }
    #endif
    
    #if NET35
            public void Net35()
            {
            }
    #endif
    
    #if NET40
            public void Net40()
            {
            }
    #endif
        }
    }



The only pain I have really encountered so far is getting MVC web applications to play nicely.

Tuesday, June 29, 2010

Object Pool Pattern

In the last post I discussed the Multiton pattern and this post continues the theme of non-GoF patterns by looking at Object Pool, another specialised Singleton. The purpose of this pattern is to re-use object instances to avoid creation / destruction. My mnemonic this time is a Car Pool which is just a collection of cars for my purposes:

public sealed class Car
{
    public Car(string registration)
    {
        this.Registration = registration;
    }

    public string Registration
    {
        get;
        set;
    }

    public override string ToString()
    {
        return this.Registration;
    }
}

The pool implementation also uses weak references to handle garbage collected cars which have not been explicitly returned to the pool:

using System;
using System.Collections.Generic;
using System.Linq;

public sealed class CarPool
{
    private static CarPool _pool = new CarPool();

    private CarPool()
    {
        this.Cars = new Dictionary<Car, WeakReference>();
    }

    public static int Availability
    {
        get
        {
            int value = 0;

            lock (_pool)
            {
                value = _pool.Cars.Where(x => null == x.Value || !x.Value.IsAlive).Count();
            }

            return value;
        }
    }

    private Dictionary<Car, WeakReference> Cars
    {
        get;
        set;
    }

    public static void Add(params Car[] cars)
    {
        foreach (var car in cars)
        {
            lock (_pool)
            {
                _pool.Add(car);
            }
        }
    }

    public static Car Get()
    {
        Car result = null;

        if (0 < CarPool.Availability)
        {
            lock (_pool)
            {
                var item = _pool.Cars.Where(x => null == x.Value || !x.Value.IsAlive).FirstOrDefault();

                var value = new WeakReference(item.Key);
                _pool.Cars[item.Key] = value;

                result = (Car)value.Target;
            }
        }

        return result;
    }

    public static void Return(Car car)
    {
        if (null == car)
        {
            throw new ArgumentNullException("car");
        }

        lock (_pool)
        {
            _pool.Cars[car] = null;
        }
    }

    private void Add(Car car)
    {
        this.Cars.Add(car, new WeakReference(null));
    }
}

Here is a test which verifies the expected behaviour:

using Xunit;

public sealed class ObjectPoolFacts
{
    [Fact]
    public void car_pooling()
    {
        Car one = new Car("ABC 111");
        Car two = new Car("ABC 222");
        CarPool.Add(one, two);

        Car first = CarPool.Get();
        Assert.Same(one, first);

        Car second = CarPool.Get();
        Assert.Same(two, second);

        Assert.Null(CarPool.Get());

        CarPool.Return(first);
        CarPool.Return(second);

        second = CarPool.Get();
        Assert.Same(one, second);
    }
}

Multiton Pattern

I’m doing a little ‘brushing up on the basics’ at the moment and as part of that effort I am working up some pattern examples, starting with creational patterns. These include staples such as Factory Method, Abstract Factory, Prototype, Singleton and so on but there are other creational patterns which weren’t in the Gang of Four (GoF) Design Patterns book. One of these is the Multiton. I don’t know what it’s provenance is, but it is an extension to the Singleton pattern which provides centralised access to a single collection making keys unique within scope. In my example, the singleton is declared as a static member so it has application domain scope.

I like to work up examples that feel (at least somewhat) real-world as I find that these are easier to remember later on. For the Multiton pattern I decided to use the Rolodex which is simply a collection of cards for my purposes:

public sealed class Card
{
    internal Card(string key)
    {
        this.Key = key;
    }

    public string Information
    {
        get;
        set;
    }

    public string Key
    {
        get;
        set;
    }
}

The pattern defines that item creation is handled by a static factory if the key does not exist in the collection:

using System;
using System.Collections.ObjectModel;
using System.Linq;

public sealed class Rolodex
{
    private static Rolodex _rolodex = new Rolodex();

    private Rolodex()
    {
        this.Cards = new Collection<Card>();
    }

    private Collection<Card> Cards
    {
        get;
        set;
    }

    public static Card Open(string key)
    {
        Card result = null;

        lock (_rolodex)
        {
            result = _rolodex.Cards
                .Where(x => string.Equals(x.Key, key, StringComparison.Ordinal))
                .FirstOrDefault();

            if (null == result)
            {
                result = new Card(key);
                _rolodex.Cards.Add(result);
            }
        }

        return result;
    }
}

Here is a test which verifies the expected behaviour:

Xunit;

public sealed class MultitonFacts
{
    [Fact]
    public void rolodex_card()
    {
        string key = "John Doe";

        Card expected = Rolodex.Open(key);
        expected.Information = "john.doe@example.com";

        Card actual = Rolodex.Open(key);

        Assert.Same(expected, actual);
    }
}

It’s worth pointing out that, as with all Singleton patterns, the plain vanilla pattern doesn’t lend itself to unit testing as-is. The answer is to provide a wrapper for mocking purposes. Here is an example of doing so for DateTime.UtcNow:

using System;

public static class DateTimeFactory
{
    [ThreadStatic]
    private static DateTime? _mock;

    public static DateTime Today
    {
        get
        {
            DateTime value = DateTime.Today;

            if (null != _mock)
            {
                value = _mock.Value.Date;
            }

            return value;
        }
    }

    public static DateTime UtcNow
    {
        get
        {
            DateTime value = DateTime.UtcNow;

            if (null != _mock)
            {
                value = _mock.Value;
            }

            return value;
        }
    }

    public static DateTime? Mock
    {
        get
        {
            return _mock;
        }

        set
        {
            _mock = value;
        }
    }

    public static void Reset()
    {
        DateTimeFactory.Mock = null;
    }
}

Sunday, June 27, 2010

Routing TcpClient HTTP requests through the default proxy

I’m coding an HttpClient at the moment: mostly for self-education but something useful might arise as well. Here is a trivial example of making an HTTP request using the TcpClient class:

string response = null;
System.Net.Sockets.TcpClient tcp = null;
try
{
    tcp = new System.Net.Sockets.TcpClient("www.example.com", 80);

    using (var stream = tcp.GetStream())
    {
        using (var writer = new System.IO.StreamWriter(stream))
        {
            writer.WriteLine("GET / HTTP/1.1");
            writer.WriteLine("Host: www.example.com");
            writer.WriteLine("Connection: close");
            writer.WriteLine(string.Empty);
            writer.Flush();
            using (var reader = new System.IO.StreamReader(stream))
            {
                response = reader.ReadToEnd();
            }
        }
    }
}
finally
{
    if (null != tcp)
    {
        tcp.Close();
    }
}

HTTP is simply an application-level protocol layered on top of TCP, so this works fine. However, as soon as the HttpClient becomes non-trivial then debugging becomes an issue. Thankfully we have tools in place to see at what’s happening on the wire. Wireshark is an excellent tool which watches all TCP traffic on a network adapter but it is somewhat overkill for watching just HTTP traffic. Fiddler, on the other hand, is my own tool of choice for monitoring HTTP traffic. Unfortunately the code shown above won’t appear in Fiddler as-is. Fiddler acts as a proxy and the code doesn’t cater for that. The TcpClient class doesn’t either because a web proxy works at the HTTP layer rather than TCP.

In over to overcome this limitation, we can use the WebClient class to resolve the default proxy.

var requestUri = new System.Uri("http://www.example.com/");
Uri proxy = null;
using (var web = new System.Net.WebClient())
{
    proxy = web.Proxy.GetProxy(requestUri);
}

tcp = new System.Net.Sockets.TcpClient(proxy.DnsSafeHost, proxy.Port);

Now Fiddler will now happily monitor the traffic. My thanks to @srstrong, @serialseb, @blowdart, @benlovell for helping me figure this out.

Saturday, June 26, 2010

Run StyleCop on every build

I first started using StyleCop during a couple of projects with Microsoft Services when it was called Source Analysis and I’m a big fan because it helps makes code consistently formatted across a codebase. In order to have StyleCop run on every build, simply open the project file in the text editor of your choice (or you can unload the project from within the solution and then right-click to edit within Visual Studio) and add the Microsoft.StyleCop.targets import (I normally add it immediately after the Microsoft.CSharp.targets import):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    ...
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\StyleCop\v4.3\Microsoft.StyleCop.targets" />
    ...
</Project>

P.S. A plea to Microsoft: can we have the standard project and class templates pass StyleCop by default please?

Deploying to IIS7 from MSBuild

Here is an example of how to configure deployment of a web application on a development machine using MSBuild with the Extension Pack:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Run" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

    <Import Project="$(MSBuildProjectDirectory)\lib\trove\Framework\v2.0\MSBuild.Community.Tasks.Targets" />
    <Import Project="$(MSBuildProjectDirectory)\lib\trove\Framework\v3.5\MSBuild.ExtensionPack.tasks" />

    <Target Name="Run">
        <CallTarget Targets="Clean" />
        <CallTarget Targets="Build" />
        <CallTarget Targets="Deploy" Condition="'$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\InetStp@MajorVersion)'=='7'" />
    </Target>

    <Target Name="Clean">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Example.sln"
            Targets="Clean"
            Properties="Configuration=$(Configuration)"
            />
    </Target>

    <Target Name="Build">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Example.sln"
            Targets="Rebuild"
            Properties="Configuration=$(Configuration)">
            <Output
                TaskParameter="TargetOutputs"
                ItemName="CodeAssemblies"
                />
        </MSBuild>
    </Target>

    <PropertyGroup>
        <WebApplicationName>www.example.net</WebApplicationName>
        <WebApplicationPath>$(MSBuildProjectDirectory)\src\Web Applications\Example</WebApplicationPath>
    </PropertyGroup>

    <Target Name="Deploy">
        <MSBuild.ExtensionPack.Web.Iis7Website
            TaskAction="CheckExists" 
            Name="$(WebApplicationName)">
            <Output
                TaskParameter="Exists"
                PropertyName="WebApplicationExists"
                />
        </MSBuild.ExtensionPack.Web.Iis7Website>
        <MSBuild.ExtensionPack.Web.Iis7Website
            TaskAction="Create"
            Name="$(WebApplicationName)"
            Path="$(WebApplicationPath)"
            Port="80"
            AppPool="ASP.NET v4.0"
            Condition="'$(WebApplicationExists)'=='False'"
            />
        <MSBuild.ExtensionPack.Web.Iis7Binding
            TaskAction="Remove"
            Name="$(WebApplicationName)"
            BindingInformation="*:80:"
            BindingProtocol="http"
            />
        <MSBuild.ExtensionPack.Web.Iis7Binding
            TaskAction="Add"
            Name="$(WebApplicationName)"
            BindingInformation="127.0.0.127:80:$(WebApplicationName)"
            BindingProtocol="http"
            Condition="'$(WebApplicationExists)'=='False'"
            />
        <MSBuild.Community.Tasks.Sleep Milliseconds="3000" />
        <MSBuild.ExtensionPack.Web.Iis7Website
            TaskAction="Stop"
            Name="$(WebApplicationName)"
            />
        <MSBuild.Community.Tasks.Sleep Milliseconds="3000" />
        <MSBuild.ExtensionPack.Web.Iis7Website
            TaskAction="Start"
            Name="$(WebApplicationName)"
            />
    </Target>

</Project>

Friday, June 25, 2010

Consistent Assembly Versioning

Personally, I like to have consistent versioning applied to all assemblies from the same build. Doing this manually is a PITA so I version from my build file and I have a pattern which I apply to achieve this. I typically use subversion for my source control and I will use the Cavity project as an example:

Subversion project structure

I build from the trunk folder:

Subversion trunk folder

I have a batch file for each ‘potted’ configuration I want and, of course, the MSBuild file. Here is the release batch file:

MSBUILD build.xml /p:Configuration=Release
PAUSE

In order to apply consistent versioning, I want to emit a Build.cs file and then link that to each project. If I want this to be a static number, I can simply configure the version directly and use AssemblyInfo task from the MSBuild Community Tasks Project:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Run" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />

    <PropertyGroup>
        <Configuration Condition="'$(Configuration)'==''">Release</Configuration>
        <Version Condition="'$(Version)'==''">1.2.3.4</Version>
    </PropertyGroup>

    <Target Name="Run">
        <CallTarget Targets="Clean" />
        <CallTarget Targets="Build" />
    </Target>

    <Target Name="Clean">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Clean"
            Properties="Configuration=$(Configuration)"
        />
    </Target>

    <Target Name="Versioning">
        <AssemblyInfo
            CodeLanguage="CS"
            OutputFile="$(MSBuildProjectDirectory)\src\Build.cs"
            AssemblyVersion="$(Version)"
            AssemblyFileVersion="$(Version)"
            AssemblyInformationalVersion="$(Version)"
            />
    </Target>

    <Target Name="Build" DependsOnTargets="Versioning">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Rebuild"
            Properties="Configuration=$(Configuration)">
            <Output
                TaskParameter="TargetOutputs"
                ItemName="CodeAssemblies"
                />
        </MSBuild>
    </Target>

</Project>

This will emit the following Build.cs:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyVersion("1.2.3.4")]
[assembly: AssemblyFileVersion("1.2.3.4")]
[assembly: AssemblyInformationalVersion("1.2.3.4")]

However, I normally use the subversion Revision number as the build number to be able to identify what was built. To do this you will need to install the CollabNet Subversion client in order to be able to query the subversion repository. Once installed, you can then use the following build file to emit a dynamic version number by utilising the SvnVersion task:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Run" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />

    <PropertyGroup>
        <Configuration Condition="'$(Configuration)'==''">Release</Configuration>
        <Version Condition="'$(Version)'==''">1.2.3</Version>
        <Revision>0</Revision>
    </PropertyGroup>

    <Target Name="Run">
        <CallTarget Targets="Clean" />
        <CallTarget Targets="Build" />
    </Target>

    <Target Name="Clean">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Clean"
            Properties="Configuration=$(Configuration)"
            />
    </Target>

    <Target Name="Versioning">
        <SvnVersion LocalPath=".">
            <Output TaskParameter="Revision" PropertyName="Revision" />
        </SvnVersion>
        <AssemblyInfo
            CodeLanguage="CS"
            OutputFile="$(MSBuildProjectDirectory)\src\Build.cs"
            AssemblyVersion="$(Version).$(Revision)"
            AssemblyFileVersion="$(Version).$(Revision)"
            AssemblyInformationalVersion="$(Version).$(Revision)"
            />
    </Target>

    <Target Name="Build" DependsOnTargets="Versioning">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Rebuild"
            Properties="Configuration=$(Configuration)">
            <Output
                TaskParameter="TargetOutputs"
                ItemName="CodeAssemblies"
                />
        </MSBuild>
    </Target>

</Project>

Saturday, June 19, 2010

Abstracting Service Location

A couple of days ago I blogged about the Common Service Locator, how to use the ServiceLocator and how to mock the IServiceLocator interface for unit testing purposes. However, I personally feel that the Common Service Locator library didn’t complete the job. Ideally, I should not need to choose specific IoC provider whilst writing my code (or at least should not be forced to recompile my application in order to change provider) and the library doesn’t enable this.

In order to enable this use case, I’ve published a set of lightweight libraries in the Cavity project. The key library is Cavity.ServiceLocation.dll which contains one interface and one concrete class. The interface is, frankly, trivial:

namespace Cavity.Configuration
{
    public interface ISetLocatorProvider
    {
        void Configure();
    }
}

The interface is trivial simply because it’s a hook to load the provider-specific configuration data. I have provided a plain vanilla implementation for Autofac, Castle Windsor, StructureMap and Unity because each of these supports XML configuration. Here is the implementation of the Castle Windsor ISetLocatorProvider:

namespace Cavity.Configuration
{
    using Castle.Windsor;
    using Castle.Windsor.Configuration.Interpreters;
    using CommonServiceLocator.WindsorAdapter;
    using Microsoft.Practices.ServiceLocation;

    public sealed class XmlServiceLocatorProvider : ISetLocatorProvider
    {
        public void Configure()
        {
            var container = new WindsorContainer(new XmlInterpreter());
            ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
        }
    }
}

As you can see, the code is lightweight: create a container, load it with configuration data and apply the configured container to the generic ServiceLocator and you’re done. To set up Castle Windsor as your provider, you must edit your app.config or web.config, as appropriate, as follows (having a separate castle.config is optional but generally considered preferable):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section
            name="castle"
            type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
        <section
            name="serviceLocation"
            type="Cavity.Configuration.ServiceLocation, Cavity.ServiceLocation"/>
    </configSections>
    <castle configSource="castle.config" />
    <serviceLocation type="Cavity.Configuration.XmlServiceLocatorProvider, Cavity.ServiceLocation.CastleWindsor" />
</configuration>

The <serviceLocation> element type attribute points to the ISetLocatorProvider implementation you wish to use. To learn more about castle.config, see Initializing with an external configuration. To see examples of each provider, you can browse the Cavity source code.

If you prefer to specific your container via a fluent interface, then you can still employ the ISetLocatorProvider abstraction by writing a custom implementation.

More detail about using the Cavity.ServiceLocation.dll library can be seen on the Cavity Wiki. Packages for each of the four plain vanilla implementations can be downloaded as zips and the binaries are also available via trove.