Wednesday, December 15, 2010

Service locator != your container

This threw me for a few minutes today...

I have a project using Unity for IoC and I am also utilizing the Common Service Locator .

I started using the CSL later in the project and replaced my previous usages of the unity container with it.

The code for the CSL looks like this

            Dim locator As New UnityServiceLocator(container)
Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(Function() locator)
The container is my UnityContainer that has been configured, now from looking at this it would seem that calling container.Resolve() would resolve the same type as ServiceLocator.Current.GetInstance() since the locator is using the underlying container.

But I will tell you for a fact since I spent 30 minutes to determine some odd behavior was coming from the fact that I missed a line that was still using the old container.Resolve(), so two methods where asking for the same type but receiving completely different instances.

Friday, January 15, 2010

Doing a 1-* OR without the ugly operators.

Many times I have found myself with an array of values not always in a list doing a comparison such as.

Dim myName as String = "Brian";
If myName = "Ryan" Or myString = "Todd" Or mystring = "Brian" Then _
DoMyFunction()

Ugly and repetitious with only 3 options.
You do have other options such as loading into a list and using a contains method, or you can also use the case method which I am not actually improves it.

Awhile back when I found out about extensions I realized that combined with generics I am able to produce something much cleaner that is very familiar if you have ever used SQL.

Here is the VB version, although it can easily be coded in C# just the same, unfortunately my current project that I am writing this post from is VB.

_
Public Function [In](Of T)(ByVal objCompareFrom As T, ByVal ParamArray objCompareTo As T()) As Boolean
For Each compareToSingle As T In objCompareTo
If objCompareFrom.Equals(compareToSingle) Then Return True
Next
Return False
End Function

Since it extends a generic type it is accessible from any object in your code base with type safety.
Using this method you end up with code that reads like this.

If myString.In("Ryan","Todd","Brian") Then _
DoMyFunction()

Now this is just a single one to many comparison, if you find the need you can extend the idea for a many to many evaluation or even a intersect and except operator.

Tuesday, January 12, 2010

Building a makeshift hierarchical Kanban with TFS

After being exposed to Kanban I have been using it and trying to refine my Kanban skills at work with a personal board. I will not dive into how a Kanban functions or how to get started because there are many better resources to learn from. But I did start to enjoy having my process laid out and being able to keep track of my work using my own value stream.

I made a few tweaks here and there as I used it more but as our team started to migrate into using TFS to manage more of this work I noticed a big duplication of efforts. I would make a change to a work item and then redo that on a sticky note.
So I started to look into a way to solve this disconnect, there are some tools out there such as www.leankitkanban.com, and these look to be good tools but they leave me at the same place putting data in two places. I didn't need a new way to keep track of data, only to display and manage it.

Then I found the TFS Work Item Manager from Telerik , it also comes with a interesting project dashboard if you are one of those teams that are fortunate enough to have large flat screens up in your development area.

But for me the Work Item Manager is what I am focused on, it allows me to connect to our TFS and show my work items. It provides a replacement for most work item tasks that you will use from Team Explorer (minus the PowerTools like the template editor), but also provides the Task Board which is supposed to be the visual representation of an agile process board.

Right off it got me 80% of the way to trashing my paper copy, the only thing really made it more difficult to use was its lack of lanes. On my board I was used to having 2 extra swim lanes, one for a priority item to move through and another to push out of the way if it was blocked.
The only way I was able to simulate this behavior was to first create a new field for items called 'Flow' (I also created an optional field for Flow Reason). I created a default value of 'Normal' and two additional values for 'Stoppage' and 'Precedence'.

Once I had these created I was able to define my default grouping by 'Flow', here is a screen of what it ends up looking like for me.














This screen actually shows a custom query, it shows my projects as gray notes which is the bigger MMF's that get assigned to me. In TFS you can create links between work times, in 2008 this is just a simple two way link but in 2010 they will be adding support for full hierarchy. For project type's I create scenario's which are a user story and standard tasks to track all of the things that I need to do for a project. With the links setup you are able to click onto the details of the item on the task board to show the items related to it.

The details screen ends up looking like screen, here I have the groupings in details view set to task type.
















The only thing left that I had to do was to create the custom query for my task board to use, because I did not want all of my work items I created in support of a project to show up on the main board, it would make it cluttered and difficult to decipher.
There is no built in way to do this so I had to operate on an assumption. I assumed that anything that had a work item link must be a subset of another work item unless the item type was of 'Project Assignment'. My query string ended up as "[System.TeamProject] = @project And [System.AssignedTo] = @me And ([System.RelatedLinkCount] = 0 OR [System.WorkItemType] IN ('Project Assignment')) AND [System.State] <> 'Closed'".

Depending on how you work these assumptions may not work for you, if for instance you create a link between two tasks or bugs then it will not show the items your expecting on the main board. You could always maintain a custom field to flag an item as a top level work item but this is just more work which I am trying to avoid if the information can be inferred.