IEnumerable to CSV Extension Method

I was talking with a co-worker about an efficient and reusable way to convert a list of objects to a comma-separated list of the objects’ IDs, and we came up with a pretty cool solution using an extension method. I figured I’d share — enjoy!

void Main()
{
       var x1 = new MyClass { Id = 1 };
       var x2 = new MyClass { Id = 2 };
       var x3 = new MyClass { Id = 3 };

       var myList = new List { x1, x2, x3 };

       var csv = myList.ToCsv();

       Console.WriteLine(csv);
}

public class MyClass
{
       public int Id {get;set;}
}

public static class MyClassExtensions
{
       public static string ToCsv(this IEnumerable<MyClass> myClasses)
       {
              return string.Join(",", myClasses.Select(x => x.Id));
       }
}

/*
Result:
1,2,3
*/

Windows Workflow 4: Adding Items to a Collection

I wanted to create a workflow that executes several custom activities in parallel and adds the results from each to a shared collection. This is easily accomplished by using WF4’s AddToCollection activity.

The XAML below demonstrates the use of both the Parallel and AddToCollection activities to accomplish this task. I’m also using of the ForEach activity to iterate through my collection to display the results.

<Activity xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib">
  <Sequence>
    <Sequence.Variables>
      <Variable x:TypeArguments="scg:List(x:String)" Default="[New List(Of String)]" Name="MyList" />
    </Sequence.Variables>

    <Parallel>
        <AddToCollection x:TypeArguments="x:String" Collection="[MyList]" Item="item1" />
        <AddToCollection x:TypeArguments="x:String" Collection="[MyList]" Item="item2" />
        <AddToCollection x:TypeArguments="x:String" Collection="[MyList]" Item="item3" />
    </Parallel>
    
    <ForEach x:TypeArguments="x:String" Values="[MyList]">
        <ActivityAction x:TypeArguments="x:String">
            <ActivityAction.Argument>
                <DelegateInArgument x:TypeArguments="x:String" Name="item" />
            </ActivityAction.Argument>
            <WriteLine Text="[item]" />
        </ActivityAction>
    </ForEach>
  </Sequence>
</Activity>

Here’s the output produced by running this workflow:

Some notes about this example:

  • The XAML was written without the use of Visual Studio’s designer
  • There is a collection variable of type List<string> declared named “MyList”; this requires us to import the namespace System.Collections.Generic
  • The AddToCollection activities’ Collection properties are bound to MyList
  • The ForEach activity’s Values property is bound bound to MyList
  • The ForEach activity creates a delegate argument named “item” which is then passed in to the ForEach activity’s WriteLine activity

Posting Source Code in WordPress Posts

As a blogger that regularly posts source code, I really feel like I should’ve known about this a long time ago. I JUST learned that WordPress.com has built-in support for code formatting, and I really couldn’t be happier. My theme selection criteria was largely based on how well code would be displayed, and now I don’t need to be limited by that — hooray!

Here’s the post with all the juicy details: http://en.support.wordpress.com/code/posting-source-code/

[sourcecode language="<language>"]
your code here
[/sourcecode]
    // I am SO excited about this!

And here’s the quick & dirty:

  • Replace <language> with the desired language to enable color-formatting (e.g., css, csharp, xml)
  • If a language is not provided, “text” will be used
  • Other options, like line-highlighting and line-wrapping can be controlled by optional attributes (highlight=”1,2″, wraplines=”true/false”)
  • Code will be automatically encoded for display — no more finding/replacing <‘s and >’s!

An Easy Fix for Registry Access for 32-bit Applications in 64-bit OSes

My company has a 32-bit application that is frequently run in a 64-bit environment. There are some registry settings retrieved by this application that exist in the WoW6432Node in a 64-bit OS, but how can we make our application smart enough to look there without breaking backward compatibility with 32-bit operating systems or sacrificing future compatibility if our application is converted to 64-bit?

One option is to implement a solution like what’s described here. You can add logic to your application to determine whether the OS is 32 or 64 bit and access the appropriate key.

That’s great, but it’s a lot of work for a setting in my application that’s read once during initialization. Instead of going through all that trouble, I just implemented a simple retry algorithm to look in Wow6432Node if the key isn’t found in the default expected location.

var regKey = GetRegistryKey(@"SOFTWARE\MyCompany\Settings");
if (regKey == null)
{
    regKey = GetRegistryKey(@"SOFTWARE\Wow6432Node\MyCompany\Settings");
    if (regKey == null)
    {
        throw new InvalidOperationException(
            @"Unable to find registry key HKLM\SOFTWARE\MyCompany\Settings");
    }
}

internal virtual RegistryKey GetRegistryKey(string path)
{
    return Registry.LocalMachine.OpenSubKey(
        path, 
        RegistryKeyPermissionCheck.ReadSubTree, 
        RegistryRights.ReadKey);
}

It’s simple and it works–terrific!

Add Additional References in LINQPad

LINQPad is one of my favorite development tools. I use it all the time to do quick tests to verify thoughts or discussions that I’m having with peers. It’s terrific for building snippets for email and doing quick what-is-this-really-doing checks. (And it’s perfectly free!)

One of the not-so-obvious things that I’ve run into with LINQPad is adding references. I looked through all the menus looking for some sort of “Add References” option but found nothing!

While slightly less obvious than I would’ve liked, adding references is very easy to do: just press F4. This is the keyboard shortcut to Query Properties–which can be found in the menus–where you can add additional assembly references or import namespaces.

I loves me some LINQPad!

TFS Build Notifications Tool

I just learned about a useful tool for keeping an eye on builds in TFS. The Build Notifications tool can be accessed from the Start menu under Microsoft Visual Studio 2010 > Team Foundation Server Tools.

This tool runs in the task tray. You can configure it with which builds you want to monitor and whether to monitor for just yourself or anyone. You can also configure it to alert you for builds that are queued, started, or finished. With the alerts configured, you’ll receive pop-up notifications each time an event occurs for a monitored build definition.

Double-clicking the icon in the task tray brings up the Build Status window which shows you the last build result for each build being monitored. This is a great way to ensure that builds don’t stay broken for too long.

Making Enumerable Collections LINQ-Queryable

LINQ is one of the greatest things that’s happened to Windows programming. I love it, and I use it all the time.

Occasionally, you’ll run into an enumerable collection class that can’t be queried with LINQ because it isn’t associated with a type. This can be easily overcome by using the Enumerable.Cast<T>() method.

Here’s a quick example from MSDN:

System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("apple");
fruits.Add("mango");

IEnumerable query =
	fruits.Cast().Select(fruit => fruit);

foreach (string fruit in query)
{
	Console.WriteLine(fruit);
}

This is a great technique to use instead of settling and using a for-each loop (ick!).

TFS SDK: Improve Performance of Parent-Child Queries

I’ve been helping a co-worker with a web application that we’ll be using in lieu of generating daily stand-up reports from Excel spreadsheets connected to TFS. We want this application to retrieve a list of User Stories and their child Tasks by Iteration Path and display them per user.

One of the pain points of Excel is that refreshing our TFS queries is a slow process that keeps getting slower as more data is added. So a key requirement of this project is to have fast-running queries. We’re writing queries using WIQL, which I’ve touched on previously. WIQL has okay performance, but executing queries is an expensive operation. You can improve the performance of your application by executing larger queries and then filtering programmatically instead of doing many queries for specific information.

For this example, I have a query to retrieve all User Stories. I’m using Iteration Path to filter items to just my team.

SELECT *
FROM WorkItems 
WHERE [System.WorkItemType] = 'User Story'
    AND [System.IterationPath] UNDER 'MyTeam\'

Each of the returned User Story work items has a collection of links. If we want to retrieve all the child work items, we can look at the link type and retrieve items by Id. The most obvious solution is to loop through collection of linked work items and retrieve any children. This code does just that:

var linkType = workItemStore.WorkItemLinkTypes
    .LinkTypeEnds["System.LinkTypes.Hierarchy-Forward"];

foreach (WorkItem d in deliverables)
{
    var stories = d.WorkItemLinks.OfType<WorkItemLink>()
        .Where(x => x.LinkTypeEnd == linkType)
        .Select(x => 
            workItemStore.Query(@"
                SELECT *
                FROM WorkItems 
                WHERE [System.Id] == " + x.TargetId)
            .Cast<WorkItem>().FirstOrDefault());
}

This solution works, but it’s slow due to the number of queries being executed. We can get a great performance boost by simply retrieving the collection of Tasks and querying the in-memory collection to find each Story’s children, like this:

var userStories = workItemStore.Query(@"
    SELECT *
    FROM WorkItems 
    WHERE [System.WorkItemType] = 'Task'
        AND [System.IterationPath] UNDER 'MyTeam\'
    ").Cast<WorkItem>();

var linkType = workItemStore.WorkItemLinkTypes
    .LinkTypeEnds["System.LinkTypes.Hierarchy-Forward"];

foreach (WorkItem d in deliverables)
{
    var stories = d.WorkItemLinks.OfType<WorkItemLink>()
        .Where(x => x.LinkTypeEnd == linkType)
        .Select(x => 
            userStories.Where(us => us.Id == x.TargetId)
                .FirstOrDefault());
}

I wrote a quick test program to test the performance gained by using this technique, and the results were quite dramatic. (55.3%!)

Average time to retrieve 85 User Stories with 250 linked child Tasks:
Method A (querying per link): avg. 4817.67 ms
Method B (query for all tasks up-front): avg. 2151.33 ms

The lesson to be learned here is that it’s typically best to execute broader queries and filter programmatically rather than to execute many queries for specific information. The above example could be improved further by retrieving Tasks and User Stories in a single query. The application could then extract User Stories from the results collection and retrieve linked Tasks from the same collection by Id.