Archive for the ‘.net’ Tag

VS and SVN – Ignoring user specific files

Visual studio tends to create files that you don’t usually want to keep under source control, such as generated files, user option files, and so on. To avoid having to clean up every time you try to Add files, you can tell TortoiseSVN to ignore certain file name patterns. The following is what I usually use:

**/bin bin **/obj obj *.suo

You can set these patterns in the “Global ignore pattern” text box in the main screen of the TortoiseSVN settings dialog.

Advertisements

Configuring Projects on Multiple Instances of Cruise Control .Net

A continuous integration server is an essential tool in the box of any team – even a one man team. I’ve used a number of different servers, but in the end I’ve always come back to CruiseControl.Net. It’s a solid, no-nonsense server which has great community support. Since it supports MSBuild scripting, it lets you use almost any tool on your controlled builds; MbUnit, NUnit, NCover, and FxCop are the few I use most often, and they’re a tiny subset of all the coding goodness that can be played with.

Continuous Integration in a Very Small Nutshell

In case you’re not familiar with continuous integration (henceforth CI), the story is this: you set up a continuous integration server which will listen to your source control repository and notice when someone adds or changes something in the repository. The server will the proceed to check the changes out, and try to build. Should the build succeed, it will try to execute any other tasks you may have set it, such as running code metrics, unit tests, and so forth. If any of the tasks fails, it will raise a general hue and cry, stamp its little feet, and generally make sure everyone knows that the build is broken as soon as possible. This helps locate issues caused by the changes from two people (or one careless person) within a few minutes of check in at worst, making the task of fixing them so much easier.

You can read a more detailed discussion of CI by the Great Lord Martin Fowler.

Note: If you’re not using a source control system, such as Subversion (SVN) or CVS,I strongly suggest you stop reading now, as this article won’t help you much. What you should do instead is, download Subversion from its website, install it, and learn to love it. It will save your backside one day, trust me. The same goes for unit testing – a CI process without tests can be pretty redundant, so you’d better Google it up a bit.

Ok, CI is Useful… But Why Have Multiple Instances?

Assuming you’ve decided that CI is worth looking into after all, you may still wonder why the hell you would want to have the same project built on multiple machines. In my case, it came about due to a requirement where my team had to ensure that a product works well both on Windows XP and Vista. Many projects ago, way back in my Java days, we’d done the same with a project so we could run unit and integration tests on one machine, and performance tests on another. Since performance tests can be taxing on a machine (especially if you use a crappy one to ensure minimum hardware requirements) you don’t really want to run them on the same machine as your regular build, as they’d slow down your entire process. One of the reasons to have CI is to have fast notification when things go pear-shaped, so slowing it down by a few magnitudes is a really bad idea.

How Do You Go About It?

The following list describes the steps I follow when I’m preparing a project for Cruise Control. I usually externalize the configuration files and properties even if I have no intention of using multiple machines – they’re a lot easier to manage that way, and it allows me to configure tools and paths per server rather than per project.

Note: This is not a beginner’s guide to Cruise Control Configuration. These steps assume that you have a working project configuration to begin with, or can write one up yourself. If you need assistance, you can find a short guide to cruise control .net configuration. A web search will also return plenty of links.

  1. Externalize all paths in your build script to a properties file.
  2. Externalize your cruise control project configuration to its own file.
  3. Add server variables to your main cruise control configuration file.

Externalize all paths in your build script to a properties file

Any build script you use will invariably have a number of external dependencies, such as the executables for additional tools that contribute to the build, run unit tests, and so on. The location of these dependencies might vary from machine to machine, so what you can do is, instead of having the paths directly into your build file, write them out in a properties file instead. Both MSBuild and NAnt support this, and it’s really easy. A properties file is just an xml file with property names and values, like this:

<Project xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″&gt;
<!– Tools –>
<PropertyGroup>
<!– Root path to the sources for any project. –>
<SourcePath>c:\projects\source</SourcePath>
<!– The root folder for the build tools. –>
<ToolPath>c:\build_tools</ToolPath>



</PropertyGroup>
</Project>

And so on. You can place this file in a location which you are sure will be present in all servers (I like to create a folder called build_tools in c:, and keep this sort of thing there). To reference the properties file in MsBuild, you can use the following syntax:

<Import Project=”c:\build_tools\common.properties”/>

You can then reference properties from the file in your MSBuild script as usual. NAnt uses similar syntax; since I haven’t used it for many moons though, I’ll refer you to the NAnt user manual rather than giving you a specific example.

Externalize your Cruise Control Configuration Into its Own File

If I had to mention one thing that annoys me about cruise control, it has to be the fact that all projects have to be configured in the same file. That bugs me. Luckily, there are ways to work around this problem using simple XML techniques.

First, copy the project element for your project to a separate configuration file. We’ll modify this to make it server-agnostic in a little while, but for now, just save it somewhere safe.

Next, add an entity definition to your main ccnet.config file, like so:

   1: <!DOCTYPE cruisecontrol[
   2:     <!ENTITY myproject SYSTEM "file:c:\projects\configs\myproject\myproject.config">
   3: ]>
   4: <cruisecontrol>
   5:     &myproject;
   6: </cruisecontrol>

Where myproject.config is the name of the configuration file you just extracted. The path should point to location of the file on the server running the configuration. The entity definition will cause the XML handler to substitute the &myproject; item with the contents of the file – think of it like you’re declaring a constant.

Warning: When you modify the main ccnet.config file, the ccnet service will notice and load the changes. This does not happen when you change configuration files that are linked in using this technique, so if you change the external configuration, your changes will not be picked up until you restart the service or touch the configuration file again.

Add server variables to your main cruise control configuration file.

So far we have a configuration file that we can easily drop onto separate servers. If you’ve externalized all dependencies and placed the appropriate properties file on all your build servers, you should be good to go – except for one minor detail. The project element in your configuration file will also specify the name of the project as displayed by the web dashboard and the cctray utility, as well as the URL that cctray will point you to when you click the “Display Web Site” item. Ideally, you want to have cctray display some indication of what server each build is on, so you can easily tell which is which in case of problems. You can easily solve this as follows: in the main ccnet.config file, add the following entities:

   1: <!DOCTYPE cruisecontrol[
   2:     ...
   3:     ...
   4:     <!ENTITY serverDescription "WinXP">
   5:     <!ENTITY serverAddress "xpmachine.mybuildservers.com">
   6: ]>

This will make the &serverDescription; and &serverAddress; entities available to the ccnet.config file and any files it loads in. This means we can go to our project configuration file and change the project name and web URL:

   1: <project name="myproject-&serverDescription;">
   2:     <workingDirectory>C:\Projects\Source\myproject</workingDirectory>
   3:     <category>CSharpProjects</category>
   4:
   5:     <sourcecontrol type="svn">
   6:         ...
   7:         ...
   8:     </sourcecontrol>
   9:
  10:     <webURL>http://&serverAddress;/ccnet/server/local/project/myproject-&serverDescription;/ViewLatestBuildReport.aspx</webURL>
  11:
  12:     <triggers>
  13:         <intervalTrigger name="continuous" seconds="300" buildCondition="IfModificationExists"/>
  14:     </triggers>
  15:
  16:     <tasks>
  17:         <msbuild>
  18:             <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
  19:             <projectFile>C:\Projects\source\myproject\Build.msbuild</projectFile>
  20:             <buildArgs>/p:Configuration=Debug</buildArgs>
  21:             <targets>Build</targets>
  22:             <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
  23:         </msbuild>
  24:     </tasks>
  25:
  26:     <publishers>
  27:         ...
  28:         ...
  29:     </publishers>
  30: </project>

Cruise Control will now report the project name and URL according to the values of the serverDescription and serverAddress entities – in this case, we’ll get “myproject-WinXP” for project name, and “http://xpmachine.mybuildservers.com/ccnet/server/local/project/myproject-WinXP/ViewLatestBuildReport.aspx” as a web URL.

Warning: Avoid using spaces in the project name or any part of the URL – cctray encodes spaces into + signs which seem to confuse the web dashboard.

Note: When you change the name of an existing project, the build counter will be reset. This could cause problems if you use automatic tagging of builds.

Where To Go From Here

At this point, you should be able to set up the same project on multiple instances of Cruise Control fairly easily. Also, if you’re using the same build machine for a number of projects, you may find that you can quite easily re-use the same property files between them, and so reduce some duplication in the configurations – it will be worth it if you ever need to change folder structure, for example.

You can also look at MbUnit or NAnt’s conditional tasks, or at MbUnit’s test categories. This would allow you to specify in the properties what sort of tests you want to run on a given build server, so you could run only performance tests, or only integration tests.

Also remember that you could conceivably externalize more configuration blocks from the project configuration file – either to reuse them or to allow the definition of more finely grained, server specific blocks. Be careful with this though, as the chain of files could quickly get out of hand.

kick it on DotNetKicks.com

Validating attribute usage with PostSharp Aspects

This post expands on my previous article on PostSharp. If you haven’t already, read it here

Most of January has flown by with just one post, effectively shooting down my resolution to blog more often. In my defence, I have to state that I’ve just moved on to newer pastures, with all the re-settling in that involves.

Apart from that, I also spent a few hours twiddling with the Jasema sources, so I do have something to post about at least. 🙂

The .net attribute architecture supports an Attribute Usage definition, which is itself an attribute that can be applied to attributes. AttributeUsageAttribute determines whether said attribute can be applied to fields, methods, classes, assemblies, or any combination thereof. This allows you to identify, at compilation time, whether the attributes you have specified are used correctly, which is great.

There are situations, however, where you might want to enforce some more detailed constraints on an attribute; for example, you might want to make sure that it is only used by classes that implement a given interface, or check what parameters have been defined for it.

It is possible to implement this as a runtime check within the attribute itself, however this is not always a very elegant solution. If you check the constraints every time the attribute is invoked in some way, you’re incurring a performance hit, however slight. If one considers that PostSharp aspects may be called every time data changes in a given field, or every time a method (or even any method in an assembly is called), this may add up to quite a bit, depending on what sort of checking you’re doing.

By making this sort of check at run time, you’re also depriving yourself of compile time checking. Even if you have unit tests in place to make sure you catch incorrect behaviour. it can still take time to run the suite; wouldn’t it be a lot nicer if the compiler could be instructed to raise an error when an attribute is given the wrong parameters, or is used with the wrong sort of class?

While PostSharp aspects don’t allow you to give such instructions to the compiler, they do allow you to do something that’s so similar that the difference, to someone like me, is purely academic (so, flame me). These aspects define an OnCompileValidate method, which can be overridden in your custom aspects.

The PostSharp compile-time weaver calls these methods while weaving your aspects into the code, so you can place your validation there; this gives you the advantage of having checks run once only (hence, without impact on executing code). Consider the source below:

         
public override bool CompileTimeValidate(System.Reflection.MethodBase method) 
{ 
    if (string.IsNullOrEmpty(fieldName)) 
        throw new InvalidOperationException( 
            string.Format( 
                "ListContentChangeRecorderAttribute requires the name of a field which implements IList. Failed on {0}.{1}", 
                method.DeclaringType.FullName, 
                method.Name));  

    MemberInfo[] matchingFields = method.DeclaringType 
        .FindMembers( 
            MemberTypes.Field, 
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, 
            this.MemberFilter, 
            fieldName);  

    if (matchingFields.Length < 1) 
        throw new InvalidOperationException( 
            string.Format( 
                "ListContentChangeRecorderAttribute could not find field {0}.{1}", 
                method.DeclaringType.FullName, 
                fieldName));  

    // Determine whether the type that defines the field implements the requested interface. 
    if (!AttributeHelper.ImplementsInterface(((FieldInfo)matchingFields[0]).FieldType, typeof(IList))) 
        throw new NotSupportedException(string.Format( 
            "{0}.{1} does not implement IList.", 
            matchingFields[0].DeclaringType.FullName, 
            fieldName));  

    return base.CompileTimeValidate(method); 
} 

This code, from the custom attributes controlling undo/redo functionality in Jasema v2 (coming soon), runs a few checks on the arguments provided for the attribute at construction: first, it makes sure that the field name argument is not empty, and that the field specified there is an actual existing field in the class which declares the method decorated with this attribute. Finally, using some helper code, it makes sure that the field implements IList, a requirement imposed on it by the logic of the aspect. This sort of checking would take some performance away from the application if it was to run repeatedly, but in this way, it only ever needs to run once – since attribute arguments must be constants, you can safely assume they won’t change after compilation.

Note that although CompileTimeValidate returns a bool type, I’m throwing an exception rather than returning false if the check decides there is something wrong. This is a matter of personal preference. The default behaviour for the weaver appears to be a silent failure; that is, if an aspect fails its validation check by returning false, it is simply omitted. Since I used aspects for a specific reason, I’d much rather have them ring all sorts of bells and raise all sorts of alarms if something is wrong, rather than failing silently and leaving you to scratch your head wondering why your masterfully crafted, world conquering AOP application is not doing what you thought it was supposed to do.

Mind you, the silent failure behaviour was probably introduced to allow the use of PostSharp‘s multicast aspect functionality (like applying an aspect to all methods in an assembly starting with an “F”). This would have been rather unwieldy if it broke the build every time it encountered a situation it didn’t quite support.

So in my case here, for example, I can’t multicast this aspect, but that’s perfectly ok by me because I only intend to use it explicitly. If you think you need to have an attribute capable of multicasting safely, then simply have it return false on failure. You may also be able to get the best of both worlds by making sure that all the classes that can support your attribute have a similar name pattern, but personally that’s where I start going glassy eyed and start drifting off into massively-overlong-classname induced nightmares.