The Productive Programmer

The first part of the book covers some tools that may improve your productivity (but nothing that i did not use already). The second part covers development techniques (again, nothing new under the sun). Despite the author’s intentions i found reading The Productive Programmer a disappointment.

Posted in Book reviews | Leave a comment

Debug It!: Find, Repair, and Prevent Bugs in Your Code

A while ago i noticed that Davy Brion recommended Debug It!: Find, Repair, and Prevent Bugs in Your Code so i decided to give it a read. Although i really liked the suggested process for investigating bugs where you have absolutely no clue of what is going on, i am not convinced that this is a must read book.

Posted in Book reviews | Leave a comment

Manage It!: Your Guide to Modern Pragmatic Project Management

A while ago i noticed that more and more of my work is related to coaching and managing other developers. In order to become better at that i ordered my copy of Manage It!: Your Guide to Modern Pragmatic Project Management. A book with plenty of useful (practical) tips. Definitely worth reading!

Posted in Book reviews | Leave a comment

Sometimes you can write it better than Resharper

Here is a real-life example of when people are much better expressing intent than a tool: Consider the following code from a typical Silverlight Navigation application:

foreach (UIElement child in LinksStackPanel.Children)
{
 var hb = child as HyperlinkButton;
 if (hb != null && hb.NavigateUri != null)
 { .. }
}

Resharper proposed to write this as following:

foreach (var hb in LinksStackPanel.Children
 .Select(child => child as HyperlinkButton)
 .Where(hb => hb != null && hb.NavigateUri != null))
{ .. }

Here is what i wrote instead:

foreach (var hb in LinksStackPanel.Children
 .OfType<HyperlinkButton>()
 .Where(hb => hb.NavigateUri != null))
{ .. }
Posted in C# | Leave a comment

Setting up a self-contained build

Here is something you may have experienced already: As a newcomer on an existing project, you check out the code from source-control and discover that the build is broken. When you ask around no-one else seems to have that problem but a helpful collegue is kind enough to tell you that you can find the installers for the missing dependencies at location X (Let’s not even mention the places where those installers are not available *sigh*).

Anway, in order to avoid such a situation you could organize your solution in such a way that all the dependencies (libraries and tools) are part of it. A typical folder structure would look like this:

screenshot of typical solution folder organization

In order to get those files out of the installer and in your solution (instead of installed under %Program Files%) you could do an administrative install of the msi (eg: msiexec /a Blah.msi) but i find it easier to use Qwerty.Msi.

Here are a couple of settings you may want to add to your build configuration in order to make your self-contained build work:

<!-- Configure solution directories -->
<BasePath Condition="'$(BasePath)'==''">$(MSBuildThisFileDirectory)..</BasePath>
<BuildPath>$(BasePath)\build</BuildPath>
<SourcePath>$(BasePath)\src</SourcePath>
<ToolsPath>$(BasePath)\tools</ToolsPath>

<!-- Configure tool directories -->
<!-- the ending \ is required for the extension pack -->
<ExtensionTasksPath>$(ToolsPath)\MSBuild.ExtensionPack\</ExtensionTasksPath>
<MSBuildCommunityTasksPath>$(ToolsPath)\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
<ILMergeToolPath>$(ToolsPath)\ILMerge</ILMergeToolPath>
<SvnToolPath>$(ToolsPath)\Subversion\bin</SvnToolPath>
<!-- wix will use this property to determine the location of other files -->
<WixToolPath>$(ToolsPath)\Wix</WixToolPath>

<!-- Configure target file paths -->
<CommonTargetsPath>$(BuildPath)\common.targets</CommonTargetsPath>
<MSBuildCommunityTasksTargetsPath>$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets</MSBuildCommunityTasksTargetsPath>
<ExtensionPackTargetsPath>$(ExtensionTasksPath)MSBuild.ExtensionPack.tasks</ExtensionPackTargetsPath>

<!-- Configure WIX -->
<WixTargetsPath>$(WixToolPath)\Wix.targets</WixTargetsPath>
<WixTasksPath>$(WixToolPath)\WixTasks.dll</WixTasksPath>
<WixTargetsPath>$(WixToolPath)\Wix.targets</WixTargetsPath>
<WixTasksPath>$(WixToolPath)\WixTasks.dll</WixTasksPath>
<LuxTargetsPath>$(WixToolPath)\Lux.targets</LuxTargetsPath>
<LuxTasksPath>$(WixToolPath)\LuxTasks.dll</LuxTasksPath>
<LuxTargetsPath>$(WixToolPath)\Lux.targets</LuxTargetsPath>
<LuxTasksPath>$(WixToolPath)\LuxTasks.dll</LuxTasksPath>

With this solution in place the next ‘new guy’ does not have to waste time trying to figure out where those dependencies are ;)

Posted in MSBuild | Leave a comment

Convention over configuration with MSBuild

A while ago i blogged that i was using the TemplateFile task from the MSBuild Community Tasks Project to generate configuration files. Each project that required templating would have modified it’s csproj file as following:

<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. -->
<Import Project="$(MSBuildProjectDirectory)\config.msbuild" />
<Target Name="BeforeBuild">
 <CallTarget Targets="GenerateConfigurationFiles" />
</Target>

And each of these config.msbuild files looked as following:

<TemplateFile Template="web.template.config" OutputFileName="web.config" Tokens="@(TemplateTokens)" />
<TemplateFile Template="Config\WcfClients.config" OutputFileName="Config\WcfClients.config" Tokens="@(TemplateTokens)" />
</Target>

As you can notice the convention here is that each template file has ‘.template.’ in it’s name, and the name of an output file is the template file name without ‘.template.’.

 <!-- valide input -->
 <Error Condition="'$(SourceFile)'==''" Text="Missing SourceFile" />
 <!-- calculate destination file -->
 <RegexReplace Input="$(SourceFile)" Expression="(\.template)\." Replacement="." Count="1">
  <Output TaskParameter="Output" PropertyName="DestinationFile" />
 </RegexReplace>
 <!-- generate file -->
 <TemplateFile Template="$(SourceFile)" OutputFileName="$(DestinationFile)" Tokens="@(TemplateTokens)" />
</Target>

Now that we can do it for one file, we can do it for many files too:

 <!-- valide input -->
 <Error Condition="'$(SourceDir)'==''" Text="Missing SourceDir" />
 <!-- find all template files -->
 <ItemGroup>
  <TemplateFiles Include="$(SourceDir)\**\*.template.*" Exlude="$(SourceDir)\**\*.svn*" />
 </ItemGroup>
 <!-- process each template file -->
 <MSBuild Projects="$(MSBuildProjectFile)" Targets="ProcessTemplate" Properties="SourceFile=%(TemplateFiles.FullPath)" />
</Target>

After these core improvements we wrote a common.proj.targets file as following:

 <!-- import global variables -->
 <Import Project="$(MSBuildThisFileDirectory)\configuration.proj" />

 <PropertyGroup>
  <BuildDependsOn>CommonBeforeBuild;$(BuildDependsOn);CommonAfterBuild</BuildDependsOn>
 </PropertyGroup>

 <Target Name="CommonBeforeBuild">
  <MSBuild Projects="$(CommonTargetsPath)" Targets="ProcessTemplates" Properties="SourceDir=$(MSBuildProjectDirectory)" />
 </Target>

 <Target Name="CommonAfterBuild">
  <!--<MSBuild Projects="$(CommonBuildTargetsPath)" Targets="PEVerify" Properties="SourceFile=$(TargetPath)" />-->
 </Target>
</Project>

Now we only need to import our common.proj.targets file in projects that have template files and focus on real business problems ;)

Posted in MSBuild | Leave a comment

WCF REST: generate correct Content-Length header for HEAD request

The point of a HEAD request is to return a Content-Length header, but with an empty body. The WCF transport stack has the annoying ‘feature’ that it ‘corrects’ the Content-Length header based on the stream that is returned. With the aid of Carlos Figueira’s MyLengthOnlyStream i was able to workaround that ‘feature’ :) (I know, i know, a good old HttpHandler is so much easier to implement!)

Posted in C# | Leave a comment

Support both GET and HEAD requests on the same method with WCF REST

A while ago i had to modify an existing WCF REST service which was being consumed by BITS. Apparently the implementation has changed in Windows7 in such a way that the BITS client first makes a HEAD request to discover the file size.

The following attempts did not work:

// A method can not have both WebGet and WebInvoke attributes
[OperationContract]
[WebGet]
[WebInvoke(Method="HEAD")]
public Stream Download(string token) { }


// A method can not have multiple WebInvoke attributes
[OperationContract]
[WebInvoke(Method="GET")]
[WebInvoke("HEAD")]
public Stream Download(string token) { }

The trick is to use * as Method and handle the method related logic in your code:

[OperationContract]
[WebInvoke(Method="*")]
public Stream Download(string token)
{
 var method = WebOperationContext.Current.IncomingRequest.Method;
 if (method == "HEAD") return ProcessHead();
 if (method == "GET") return ProcessGet();
 throw new ArgumentException(method + " is not supported.");
}
Posted in C# | Leave a comment

Microsoft SQL Server 2008 Internals

Around new year i found out that i would be working with SQL Server 2008 so i needed a crash course. Microsoft SQL Server 2008 Internals is really not intended to be that, but it does cover the basics and then dives (way too) deep in detail. Although i stopped reading halfway the dives i found the book very interesting!

Posted in Book reviews | Leave a comment

Windows Internals: Including Windows Server 2008 and Windows Vista, Fifth Edition

Given the fact that i have been developing software for MS-Windows the last couple of years i found it important to learn a bit more about the internals of the operating systems on which my applications run so i ordered a copy of Windows Internals: Including Windows Server 2008 and Windows Vista, Fifth Edition back in september and learned quite a bit from the chapters that i found interesting: security, authorization, networking and analyzing crashes. I skimmed through the chapters on memory management, scheduling and file systems because they reminded me too much of Tanenbaum’s excellent Modern Operating Systems.

Posted in Book reviews | Leave a comment