How to version DLLs using TeamCity

It’s useful to include a version in DLLs that you deploy, to make it easy to check what code is actually being used where. We build our projects using TeamCity, and it’s possible to write build scripts that grab the version from an environment variable that TeamCity sets in order to insert into your AssemblyInfo.cs files. However, if you have a fairly standard project setup and are using TeamCity, there’s an easier way to do this using the AssemblyInfo Patcher build feature that TeamCity provides. This will run after all files have been checked out, automatically searching for all AssemblyInfo.cs files and replacing relevant versions (e.g. in the [assembly: AssemblyVersion("1.0.0.0")] attribute) with the current build number, before then proceeding as normal with the build, and reverting the changes once the build has finished.

To enable this feature, simply edit the configuration settings for the build you wish to add it to, click “Build Features” in the sidebar on the left, then click the “Add build feature” button and select “AssemblyInfo patcher” from the options. Configuration is fairly minimal but will allow you to customise the format of the version that will be used for various different attributes, if you don’t want to just use the default build version.

TeamCity build features

The AssemblyInfo Patcher is just a pre-configured version of the TeamCity File Content Replacer build feature, which you can use if you have more advanced needs.

Using multiple versions of the same namespace in the same Visual Studio project

I had an issue recently when using the NServiceBus.Testing library (version 2.6.0.1504, which is a bit outdated now, but the problem is still interesting). The NServiceBus.Testing library comes with the popular Rhino Mocks framework built in, so by adding a reference to NServiceBus.Testing you automatically end up with the Rhino.Mocks namespace being populated. Unfortunately, I was already using a later version of the Rhino Mocks framework in my project, so this caused a conflict. I couldn’t just remove the existing Rhino Mocks reference because I was relying on features that were not available in the version included with NServiceBus.Testing, and obviously I needed features from the NServiceBus.Testing library, so I had to find a way for the two to co-exist peacefully.

This is possible using reference aliases. By default, when you add a reference to a project, the namespaces in the reference are added with the global namespace alias. However, you can customise the alias by changing the properties of the reference, like so:

Reference alias

This stops the reference being added to the global namespace alias, which in this case meant that any references to the Rhino.Mocks namespace would resolve (correctly) to the Rhino.Mocks reference, instead of NServiceBus.Testing. When you want to use namespaces from a custom-aliased reference in a class, you need to specify the custom alias along with the extern keyword at the top, and use the alias along with a double colon :: as a prefix in the using import statements to specify where to look for a particular namespace, e.g.

extern alias NServiceBusTest;
...
using NServiceBusTest::NServiceBus.Testing;
using Rhino.Mocks;
...
namespace Tests 
{
    [TestFixture]
    public class TestClass
    {
        private Saga<MySaga> _saga;
        private ISomeDependency _dependency;

        [SetUp]
        public void CreateSaga()
        {
            _dependency = MockRepository.GenerateMock<ISomeDependency>(); // resolves to the actual Rhino Mocks reference
            _saga = Test.Saga<MySaga>(); // comes from the NServiceBus testing framework
        }
    }
}

Job’s a good ‘un.

Nested elements in custom NAnt tasks

There’s a great post¬†here¬†detailing how to add nested elements within a custom NAnt task. I was writing a task to create IIS websites, and wanted to be able to specify multiple bindings, for example:

<IIS.Website.Create name="MySite" physicalPath="path">
    <bindings>
        <binding type="http" ip="1.2.3.4" port="8080" host="domain.com" />
        <binding type="net.msmq" host="localhost" />
    </bindings>
</IIS.Website.Create>

The important NAnt attributes you’ll need to know about are:

  • BuildElement – denotes a property as representing a nested element within a task, e.g. the <bindings> element above
  • BuildElementArray – denotes a property as representing an array of nested elements, e.g. the set of <binding> elements above
  • ElementName – used to denote a class as representing a build XML element

and the relevant NAnt classes are:

  • DataTypeBase – provides the abstract base class for NAnt types
  • Element – represents a build XML element

In simplified summary, to allow the XML snippet shown at the beginning of this post to be used, you will need to:

  • Create a class to represent the <binding> element, which derives from Element and is attributed with ElementName:
    [ElementName("binding")]
    public class IisBinding : Element
    {
        [TaskAttribute("type")]
        public string Type { get; set; }
    
        [TaskAttribute("ip")]
        public string IpAddress { get; set; }
    
        [TaskAttribute("port")]
        public int Port { get; set; }
    
        [TaskAttribute("host")]
        public string Host { get; set; }
    }
    
  • Create a data type that will represent a set of those <binding> elements. The crucial part is the BindingElements array. You’ll note that this class creates a representation of the IIS bindings (IisBindingDescription) from the elements in the array – you might just use the elements directly, depending on the scenario.
    [ElementName("bindings")]
    public class IisBindingSet : DataTypeBase
    {
        private readonly IList<IisBindingDescription> _bindings = new List<IisBindingDescription>();
    
        public IList<IisBindingDescription> Bindings
        {
            get { return _bindings; }
        }
    
        [BuildElementArray("binding")]
        public IisBinding[] BindingElements
        {
            set
            {
                foreach (var binding in value)
                {
                    ParseBinding(binding);
                }
            }
        }
    
        private void ParseBinding(IisBinding binding)
        {
            ...
    
            _bindings.Add(new IisBindingDescription(type, bindingInformation));
        }
    }
    
  • N.B. for completeness’ sake, this is the IisBindingDescription class – it’s just a DTO.
    public class IisBindingDescription
    {
        public string Protocol { get; private set; }
        public string Information { get; private set; }
    
        public IisBindingDescription(string protocol, string information)
        {
            Protocol = protocol;
            Information = information;
        }
    }
    
  • Add a property to your task with a BuildElement attribute, which unfortunately must also specify the name for the data type element – this must match the name used in the ElementName attribute used when creating the data type.
    [BuildElement("bindings")]
    public IisBindingSet Bindings { get; set; }
    

That’s all there is to it! Now, if you used the XML snippet from the top of this post in your build file, you would end up with two IisBindingDescription objects available in the Bindings property (and two elements in the BindingElements property, if you wanted to use them directly) of the IisBindingSet, which can be used where required.

It should be possible to use the BuildElementArray directly in your Task class, if you didn’t want a surrounding type. Also, there is a BuildElementCollection attribute, which I imagine acts very similarly to BuildElementArray but allows you to use a collection type instead.

ANTLR and C#

I’ve just spent the day getting ANTLR set up to work within a Visual Studio 2010 solution, which wasn’t without pain. While there is quite a lot of (mostly useful) documentation, finding exactly what you want can be difficult, and the examples don’t necessarily work, which is always frustrating! Hopefully this will help someone else along the way. It’s obviously written from my perspective and I’ll be making no attempt to generalise it to other situations, but there’s naturally going to be crossover with other stuff.

To get started, the following sources proved helpful:

The details in this post simply extend what is available in those documents.

First, let’s get Visual Studio 2010 set up ready to work. The simplest way to get the ANTLR VS extensions is to open up the Extension Manager (Tools -> Extension Manager) and search the online gallery for the following packages:

  • ANTLR Language Support
  • StringTemplate 4 Language Support

Install them both, and you’ll notice that the Tunnel Vision Labs Extensibility Framework extension will also be installed automatically. You can if you prefer download the extensions directly (links taken from (2)):

However, note that if you download from the above links, not only are those versions out of date, if you try to update them using the Extension Manager, it will throw an error saying that the VS Extensibility Framework is already installed, and it doesn’t seem to be able to handle updating that.

With these installed, you’ll get syntax highlighting, dropdowns of parser and lexer rules where your class and method dropdowns usually are respectively, and a bunch of templates for creating gammars, which you can find easily by typing “ANTLR” in the search filter when adding new items.

So for us to get started, you’ll need to create yourself a new console application project, call it AntlrTest if you like.

Now you’ll need the C# port of ANTLR. At the time of writing, the latest version could be downloaded from http://www.tunnelvisionlabs.com/downloads/antlr/antlr-dotnet-csharp3bootstrap-3.3.1.7705.7z, which contains just the files you’ll need to generate C# code from ANTLR. (To make sure you’ve got the latest version, you can go to http://www.antlr.org/wiki/display/ANTLR3/Antlr3CSharpReleases and look for the bootstrap version to download.) Once you’ve downloaded the archive, extract it to a suitable place within your solution – for me, I tend to use a lib folder for references, so I extracted everything to .\lib\Antlr

To integrate the code generation into your build, you’ll need to edit your project file manually. Unload your VS project (right click on project, select Unload Project) and open it for editing (right click on the project file, click Edit AntlrTest.csproj, for example). Note: you can save yourself a click here by using the PowerCommands (see here). Now look for the following line:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

and below it, paste the following code:

<PropertyGroup>
  <AntlrBuildTaskPath>$(ProjectDir)..\lib\Antlr</AntlrBuildTaskPath>
  <AntlrToolPath>$(ProjectDir)..\lib\Antlr\Antlr3.exe</AntlrToolPath>
</PropertyGroup>
<Import Project="$(ProjectDir)..\lib\Antlr\Antlr3.targets" />

Obviously if you have your ANTLR files in a different directory to me, you’ll need to change the above paths accordingly. You can now go ahead and reload the project (right click, Reload Project) and if everything’s going smoothly the project should reload, without any noticeable changes. You’ll also need to add a reference to the ANTLR runtime assembly, which is located at .\lib\Antlr\Antlr3.Runtime.dll.

At this point, your project is ready to generate code using ANTLR and link it into compiled assemblies – the well written Antlr3.targets file takes care of all that. However, if you want to write any C# code within VS, rather than inside ANTLR grammar files, and have IntelliSense working, you’ll need to go through a bit more effort at this point. The trouble is that the bundled targets file generates the C# code to the intermediate obj directory during the build process. We want to have those generated files within our solution, but we don’t want to be pointing to them within a specific build configuration folder, e.g. obj\x86\Debug, because that can lead to all kinds of problems when we change configurations etc. So, we need to generate the files to a known location regardless of build configuration, and link to them there. Also, we need to stop the files being included automatically by the ANTLR target, since they’ll already be included in our solution and we don’t want to link to them twice. Luckily, this has all been done for you by a certain G. Richard Bellamy, who has updated the Antlr3.targets file for this purpose. Go to http://youtrack.jetbrains.net/issue/RSRP-265402, download the Antlr3.targets attachment (found at the top of the page) and drop it into your Antlr folder (.\lib\Antlr), replacing the existing targets file. Now, whenever you build the project, the generated C# code from the ANTLR grammar file will be put in a folder called Generated in the same location as the grammar file. If you want to change the name of this folder, simply open the Antlr3.targets file and replace any instances of .\\Generated with your preferred folder (note: it’s written more than once, because the folder is specified as the output location for generated files but is also mentioned later on so that the redundant .tokens files can be cleared from the generated folder).

Great, so let’s see this all in action. There’s a sample grammar shown in (1) which I’ve taken for this example with a bit of modification. Start by adding a grammar file by adding a new item and choosing ANTLR Combined Parser. Call it SimpleCalc.g3 (g3 means grammar 3, as we’re dealing with ANTLR v3 grammars here) and click Add. A combined grammar specifies rules for lexing and parsing an input. Therefore you’ll notice three files are created for you:

  • SimpleCalc.g3 – the ANTLR grammar file itself
  • SimpleCalc.g3.lexer.cs – a partial class for adding functionality to the lexer
  • SimpleCalc.g3.parser.cs – a partial class for adding functionality to the parser

The partial classes are useful if you want to extend your generated classes without having to specify C# code in your grammar file, which obviously offers a whole host of benefits. One other thing to note is that if you look at the properties of SimpleCalc.g3, you’ll notice that the build action is set to Antlr3 and the custom tool set to MSBuild:Compile. The extension kindly deals with setting these properties for you, but if you ever added files manually you’d need to do that yourself. These settings mean that the Antlr3 target is called whenever the file is built (so generated files are created), and the custom tool setting ensures that whenever you save the file, due to the carefully crafted targets file, the C# code will be re-generated and IntelliSense will be updated, which is rather nifty.

Open up SimpleCalc.g3, and you’ll see some skeleton code that the extension creates for you. For now, we’ll just overwrite this completely with our own example:

grammar SimpleCalc;

options {
    language=CSharp3;
}

tokens {
	PLUS 	= '+' ;
	MINUS	= '-' ;
	MULT	= '*' ;
	DIV	= '/' ;
}

@lexer::namespace { AntlrTest }
@parser::namespace { AntlrTest }

/*
 * Parsing rules
 */

public expr	: term ( ( PLUS | MINUS )  term )* ;

term	: factor ( ( MULT | DIV ) factor )* ;

factor	: NUMBER ;

/*
 * Lexing rules
 */

NUMBER	: (DIGIT)+ ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ 	{ $channel = Hidden; } ;

fragment DIGIT	: '0'..'9' ;

Copy and paste that into your grammar file. One gotcha to note: blogs/wikis sometimes use a different Unicode character for whitespace, such that when you copy this into the Unicode-compliant VS, it will preserve those special characters without you knowing. Trouble is, ANTLR can’t handle them, so when you try to build your project you’ll end up with an error similar to error(150): grammar file AntlrTest.g has no rules. To avoid this, it might be a good idea to copy the example into something that doesn’t preserve Unicode, e.g. Notepad, and then copy again from there. This caught me out when I first copied the example from (1), but now I can’t reproduce it!

It’s also worth noting at this point that:

  1. the grammar name has to be the same as the filename it’s stored in: if you change one, you must change the other, and
  2. the ordering of elements within the grammar file can be quite important: when ANTLR is parsing a grammar it can be picky about where elements are located.

Having copied over that grammar, let’s look at the differences between that and the example shown at (1), and why I’ve made them.

  1. language changed to CSharp3 – the CSharp2 target is outdated
  2. Added in namespaces for the lexer and parser – these are required for the partial classes we have to be able to combine with the partial generated classes (these are added in automatically for you by the extension)
  3. Removed the @members { ... } section – this will be explained further down the page…
  4. …as will the reason for adding the public modifier to the expr parser rule
  5. Change of case in $channel = Hidden; – the constant Hidden simply has a different name in C# to align with conventions (its value is 99 so you can also use that instead)

At this point, build your project. Hopefully it will finish successfully, and you can now add those generated files into your project so we can see them. Add an existing item to your project, and look in the Generated folder (that we talked about earlier), where you should see two files: SimpleCalcLexer.cs and SimpleCalcParser.cs – add these as links to your project. Obviously it’s important you add as links otherwise you won’t pick up any changes when the files are regenerated. Having now got these files into our solution, you can have a poke around and see what ANTLR is doing for you; there’s more documentation on the ANTLR website about what exactly is generated, so for now I’ll move on.

Back to that @members { ... } I kicked out. While you can write C# code within the grammar file, which will then be included within the generated class, it’s much preferable to do it within a proper separated class file (which is why our helper partial files exist). Case in point: if you actually copy and try to build that example, you’ll notice it will fail because the generated file is missing a vital using System; for Console, which is a mistake you obviously wouldn’t make if you were editing within a proper class file (note: you can also fix this issue by adding @headers { using System; } to the top of your grammar file). Therefore, I took the code from that section, modified it and put it into the Program.cs file that was added when we created the project:

using System;
using Antlr.Runtime;

namespace AntlrTest
{
    class Program
    {
        public static void Main(string[] args)
        {
            const string input = "1+4/2";
            var lex = new SimpleCalcLexer(new ANTLRStringStream(input));
            var tokens = new CommonTokenStream(lex);
            var parser = new SimpleCalcParser(tokens);

            parser.expr();
        }
    }
}

You’ll notice I removed the try ... catch block that’s used in the example from (1). This example seems to be out of date since I noticed that RecognitionExceptions are now caught within the generated code, so they’ll never be thrown to be caught at this level. The errors are supposed to be outputted by the BaseRecognizer, but it looks like a TextWriter property needs to be set and presumably isn’t being – I didn’t have time to work out why. It’s easy for now to get errors printed on the console by making use of our partial classes (handy example), by adding the following to both the lexer and the parser:

public override void EmitErrorMessage(string msg)
{
    Console.WriteLine(msg);
}

Copy all that code into the relevant places and build your project. I’ve changed the input to the lexer to be an ANTLRStringStream so we can easily play with it (it’s a file reader in the example from (1)). If everything’s gone to plan the build will be successful and you should be able to run the program… and nothing will happen. That means success! Why? Because all we’re doing here is attempting to parse the input, nothing more. Because our input is valid, nothing will be printed to the console, and so the program will terminate with seemingly nothing happening. Try replacing the input with something nonsensical (e.g. GEORGE) and watch as the parser spews out errors. Beautiful.

Now I’ll clarify why I added that public keyword to the expr parser rule earlier on. The CSharp3 target introduced the concept of modifiers on parser rules. By default, all generated parser rule methods are set to private. If we’d left the code in that member section in the grammar file, we wouldn’t have needed to change the modifier, since the method would have been copied to the generated file and therefore been able to access the private method. However, since we’re attempting to access it from outside that class, in our separate Program class, we need to make it public. It would possibly have been a better idea to add a method to the partial parser class that allowed us to access that private rule, but I left it as it is as a nice example of how and why the modifiers might be used.

Phew. Now you should have an idea about how to get started using ANTLR grammars within C#. The above example doesn’t output anything (you’ll notice the return type of the expr() method is void), so it’s not very useful, but by adding the line output=AST; to the options section of the grammar file (as shown in the skeleton grammar files generated by the extension), the parsing rules will return a result object describing the parsed expression that you can play with. I think I’ve written enough for one day though.

Fluent null checking

When you want to access nested properties on an object, e.g. Person.Address.Postcode, it’s annoying and bloated having to write this as a series of variable assignments and null checks at each stage if the properties are nullable. The set of extensions below allows the following example:

public string GetSomething(A myClass) {
    var property1 = myClass.Property1;

    if (property1 == null) {
        return string.Empty;
    }

    var property2 = property1.Property2;

    if (property2 == null) {
        return string.Empty;
    }

    return property2.Property3 ?? string.Empty;
}

to be cleanly re-written as…

public string GetSomething(A myClass) {
    return myClass.With(x => x.Property1).With(x => x.Property2).Return(x => x.Property3, string.Empty);
}

using these extensions:

using System;

namespace Extensions
{
    public static class MaybeMonadExtensions
    {
        public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
            where TResult : class
            where TInput : class
        {
            return o == null ? null : evaluator(o);
        }

        public static TResult Return<TInput, TResult>(
            this TInput o,
            Func<TInput, TResult> evaluator,
            TResult failureValue)
            where TInput : class
        {
            return o == null ? failureValue : evaluator(o);
        }

        public static TInput If<TInput>(this TInput o, Func<TInput, bool> evaluator)
            where TInput : class
        {
            if (o == null)
            {
                return null;
            }

            return evaluator(o) ? o : null;
        }

        public static TInput Unless<TInput>(this TInput o, Func<TInput, bool> evaluator)
            where TInput : class
        {
            if (o == null)
            {
                return null;
            }

            return evaluator(o) ? null : o;
        }

        public static TInput Do<TInput>(this TInput o, Action<TInput> action)
            where TInput : class
        {
            if (o == null)
            {
                return null;
            }

            action(o);
            return o;
        }
    }
}

See http://www.codeproject.com/KB/cs/maybemonads.aspx for more details.

Extension to calculate age

using System;

namespace Extensions
{
    public static class DateTimeExtensions
    {
        public static int Age(this DateTime birthDate)
        {
            return Age(birthDate, DateTime.Today);
        }

        public static int Age(this DateTime birthDateTime, DateTime atDateTime)
        {
            var birthDate = birthDateTime.Date;
            var atDate = atDateTime.Date;
            var age = atDate.Year - birthDate.Year;

            if (birthDate.AddYears(age) > atDate)
            {
                age--;
            }

            return age;
        }
    }
}

Accessing clipboard from a C# console application

Simple, but a few non-obvious things required:

1. Add a reference to System.Windows.Forms
2. Add a [STAThread] attribute above the Main method (see here for more information)
3. Now you’re ready to use the methods on Clipboard to write to the clipboard:

...
using System.Windows.Forms;

namespace MyNamespace
{
    public class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Clipboard.SetText("Text to put on the clipboard");
        }
    }
}

Using ELMAH with MVC 3

Whereas ELMAH used to work pretty much straight out of the box, with MVC 3, a change to the global.asax.cs template means that ELMAH won’t automatically catch all errors, since MVC 3 has some built in error handling when custom errors are enabled. To remove this and let ELMAH catch everything, make sure you’ve removed the following line from your global.asax.cs file:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute()); // remove at least this line
}

(Note: if you read this wondering what ELMAH is, go here to catch up)