Subscribe
Sign In
|
 Wednesday, June 20, 2007
In a previous post I described some of the simple things we have used at work to improve our TFS life as developers, and today I thought I would share some finer detail.
One of the single greatest tools I use to combat TFS weariness today is this fantastic outlook add-in by the SRL Team. It has changed the way our company works with TFS, I highly recommend installing it. In short you can create work items (tasks, bugs etc) from outlook items (emails, tasks etc) and also search TFS by keyword or ID.
Another tool of note, which aids those who need to access TFS reports and source on the run, is TeamPlain, which I use at home quite a lot. This gem provides a much better web interface for developers than the standard portal TFS currently provides. Whilst you can't do bulk checkouts very easily, simple one file check-ins/outs are quite doable. I find it particularly useful for creating work items and running reports when I don't have intranet access to work. It's so good, that Microsoft actually bought the company who created it, and is now a free download. Please note, this doesn't suddenly earn you a portal for non licensed developers – you will still need CAL's for users on TeamPlain.
The TFS Administration Power Tool is the only way to fly when you need to setup permissions for new TFS users in a hurry. It streamlines the task of setting up permissions for TFS, Share point and reporting services in one place. Perhaps its greatest feature that puts it over the line for hard core command line users is that you can easily make multiple changes at once. It also displays the activity log for all changes made, in case you need to blame somebody else for some poorly configured permissions. ;)
Lastly, but certainly not least, if you haven't already downloaded it, then do yourself the favour of getting the TFS Power Tools. For starters tftp.exe has some excellent command line functionality for managing all manner of day to day TFS tasks; tree clean, undo unchanged, to name but a few. There is a myriad of commands and it is very easy to pickup. Along with tftp.exe there is the check in policy pack which has some fairly common check in policy examples for you to utilise. If you want to implement your own custom check-in policies, it isn't hard and I suggest you have a look at Marcel de Vries primer on the topic.
On the topic of check in policy, we recently added one more to our front line against bad check-ins: for VB projects option strict must be turned on. <Cue-sniggers-from-the-C#-crowd/> I think it's imperative that any serious VB development be done with Option Strict on (and Option Explicit, but luckily the power of defaults has saved us here.) There was once a time when I thought the idea of duck typing and implicit casting was convenient and I'm certainly not proud of those days. Coming from a C programming background I should have known better, but I was well and truly caught by the Dark Side™.
There are few things worse than being asked to maintain some buggy code, that has Option Strict off, and after turning it on you get an error telling you that the amount of errors that can be displayed has been exceeded.
So how does this all help us to know ourselves better? Do some fancy add-ons to an already confusing product actually make project analysis any easier? The short answer is YES. Basically, the two things you need in order to make effective use of the TFS data warehouse are as follows:
- Some understanding of DML queries (I can tell you, my T-SQL chops are infantile at best)
- A solid set of data
By encouraging your team to create good check-in data with easy to access tools, querying TFS data becomes a much more fruitful experience. If you only have one task to check in against, then querying check-ins really isn't going to give you answers on how long a particular feature took to achieve. Conversely, if you have a rich source control history then ascertaining the amount of time a feature took to implement is a sinch. That's just the beginning; this data store can lead to all sorts of revelations about productivity and quality. It's all about granularity, and it's easy enough to provide. At work we use the following conversion to provide a decent work item tree:
- Product = Area
- Feature or functionality = Scenario
- Aspect of functionality = Task
- Development cycle (design, create, test etc) = Iteration
- Bugs are well, bugs of course.
Areas contain Scenarios, Tasks and bugs are assigned to Iterations. We create related work items from a Scenario when creating a new task or bug, so that they have some link. We don't really bother with Quality of Service or Risk items, but if you feel they apply to your product, by all means use them. We have started to store function specifications into TFS using this convention in order to kill the proverbial two birds. Firstly, it gives us a structured and consistent means of entering a function spec, and also provides a convenient skeleton to create work items from.
The net result is that if Mr. CEO would like to know how application X is coming along, we can immediately ascertain which scenarios have or haven't been satisfied (I.E % completion). If Mr. Lead Dev wants to know how many tasks to add to an Iteration, he can look up the project velocity report (a standard TFS report) to get a good idea of how quickly his team churns through tasks per day.
In my next post I will give some examples of querying against the TFS warehouse and how it can make your life a little easier when the boss starts asking the hard questions.
 Friday, June 08, 2007
Came across this handy technique for testing that methods are raising the correct events. I hope its of use.
[TestMethod] public void RaisesMyEventCorrectly() { bool lRaised;
MyObject obj = new MyObject; obj.MyEvent += delegate { lRaised = true; }; MyObjectWithEvents.Method();
Assert.IsTrue(lRaised, "MyEvent did not fire as expected."); }
 Wednesday, June 06, 2007
We've been using Team Foundation Server for well over 12 months at my workplace, and it's been quite a journey. This post is the first in a short blog series about some of the different things we have come to use and some of things we don't bother with.
I honestly believe it has made us better developers in the process, if only for implementing a check in policy. Currently, we have a simple policy; we weren't looking for a mechanical office Nazi. Our implementation includes the following rules:
- Must provide some comments to accompany your check-in. Just some brief detail about the change set.
- Must associate the check-in with a work item, be it bug, task, scenario, quality of service or risk.
- Must enable code analysis on your project. Unfortunately we haven't been quite able to enforce turning all the CA rules on *yet*. However CA must be on with a few of the more important rule sets also enabled.
Summarizing your check in forces you to think about exactly what you are trying to achieve with your change set. It also proves invaluable when the proverbial chairman of the board wants to see an out-of-the-blue-activity-report on a particular project, as happened to us about a month ago. Obviously somebody could type "qwerty" and check in however, I think we can all agree a little bit of honesty with oneself can go a long way in this game.
TFS Work items are the end of To-Do's in code in my mind. I don't like seeing To-Do's in code because they are often little more than unheard cries for help. Unless you are using some proprietary software to aggregate your To-Do's solution wide, they are largely lost. Visual studio doesn't jam them in your face as you open a solution, so if you aren't looking for them, chances are you wont find them until you are deep in some other time consuming task.
A much better approach is to have a repository of things to do, and at some point decide who will do them, and when to do it. TFS provides this functionality in droves. For starters you can create TFS work items directly from your bug list. You can sort, report and assign work items to other members of your team. From the get go, you have everything you need to create and manage a to-do list. Iteration planning is obviously aided by this documented list of required bug fixes and 'version next' ideas, which augment the list provided by your user base.
Having a thriving list of work items means that checking in against a work item (and hopefully marking it as having been finished) completes the circle and provides yet more valuable history information. By enforcing this action at check in time, we ensure we have at least some premeditation of our change set going on. Additionally, we can easily report on change sets for a particular task, and quickly determine just how long it took to achieve a particular feature or solve a particular bug. Once again, such info is invaluable for iteration planning.
Enabling Code Analysis is still, IMHO, a personal choice. I believe it should be on in some capacity, but blindly following code analysis rules as some sort of mantra to better development is foolish. Take unit testing for instance. Some popular testing frameworks would like to see your unit tests as public, non static subs. However, FxCop will invariably spot that no class instances are required for this function, and promptly tell you to mark your test as static (or shared in VB). The CA acolyte who changes his or her entire test suite to static methods will invariably find that the entire suite fails to run. I work on a policy of turning on every CA rule available and if it becomes apparent that a certain rule is demanding something unreasonable for the situation, I turn that particular rule off. FxCop is not perfect. Neither are you, but together we can achieve greatness.
By taking advantage of TFS check in policy, and by embracing some of the simpler aspects of TFS life (creating work items) you will find you can learn all manner of information about how your teams actually works, which can often mean the difference between success or failure. To know your enemy is to conquer them: and we are our own worst enemy.
In my next post I will elaborate on other means by which work items can be organized and created, and some examples of simple TFS queries to get some finer detail about what is going on.
 Sunday, June 03, 2007
A triptych inspired by the coldest of months. For readers in the southern hemisphere, welcome to winter.
 Friday, June 01, 2007

1280x1024 1280x960
Ok, this counts as the very first desktop published here on Nervoustych! This image was inspired by a recent trip to CodeCampOz in Wagga Wagga. Jason and I were lucky enough to receive funding from work to join the wonderful group of developers there in April this year.
I do hope this image can say more about the Hay Plain than I can.
If you want this image in a different resolution just let me know and I'll make it available here. Can do double and triple monitor renders if you so desire.
 Thursday, May 31, 2007
A good friend of mine, and work colleague Jason Stangroome alerted me to the fact that JetBrains ReSharper 3.0 Beta has recently started. Possibly one of the biggest steps forward is its complete VB support. In the past VB support was limited to very few features. There is now a serious alternative to Refactor Pro! for VB addicts. Other things of note include: I currently use MZ-Tools for code templating at the moment, its a great set of odds and ends to help you develop in Visual Studio, and the templating functionality is quite useful. The best part is that its dirt cheap. I'm also working on a better snippet interface for Visual Studio, which I'll brag more about when there is somethig to show. For VB projects I have Refactor installed, which is an absolute boon, however I have tried many a time to install CodeRush trials to give it whirl, and have been left with nothing but frustration. ReSharper is definitely worth owning, having used 2.0 and 2.5 for fleeting trial periods, I'm already a big fan. I havent been able to justify the cost, since most of the present work I do is in VB. Now that 3.0 is touting VB support, that just became the justification I needed. Can you tell I'm excited? Im looking forward to getting hooked on this tool, apparently its as addictive as crack, just better for your health.
 Wednesday, May 30, 2007
About a year ago, while designing a few windows forms that pulled in data from typed datasets, I came across a rather annoying forms designer issue that was a little obscure to solve. Lately some other members of the team have been confronted with the same issue.
When attempting to change a data property in the Properties window for some components, for instance the DataSource or DataMember properties. The following message pops up in a message box without any further information: "Object reference not set to an instance of an object."
The solution is quite simple, by opening the 'Show Data Sources' window you are presented with a list of potential data sources to create bound controls from. It just so happens that this list will, on occasion, show an old data source that is no longer available. Luckily for us these 'dead' sources are easily identifiable by their icon (a small red cross from memory), and you can delete them. Doing so will correct the issue immediately.
This is the point where it starts making a little more sense I guess; the properties window uses an editor control to display a list of components in your project that can be bound to. This editor must use a similar method of discovery as the show data sources view, but its handling of null references during the enumeration of child objects obviously is less than sound.
Incidentally, if you are writing controls that need to be bound to data from something like a BindingSource, using the following pattern will allow your control to appear like other framework controls:
using System.ComponentModel;
private object _DataSource;
[AttributeProvider(typeof(IListSource))] [Category("Data")] [RefreshProperties(RefreshProperties.Repaint)] public object DataSource { get { return _DataSource; } set { _DataSource = value; } }
System.ComponentModel.AttributeProviderAttribute is the attribute which tells the property grid to use its IListSource editor. The RefreshPropertiesAttribute attribute tells property editors how to refresh other properties when the value of the marked property changes. The CategoryAttribute simply positions the property in the properties grid to the desired category, when the property grid is in category view.
 Tuesday, May 22, 2007
I have recently been tasked a data conversion that requires me to convert from SQL Data into XML, via a schema (not my design), the resultant XML data going to a BLOB table. Don’t ask.
I battled with a number of options but finally settled on a two step process. I'm using XSLT for the bulk of the work, with a sprinkling of VB to take care of some stuff that needed to use some existing .NET libraries of ours.
Like most developers I'm often looking for the tool that will speed up my development process and reduce the amount of code I have to write. So I tried using Altova's latest offering in the MapForce range to handle the mapping between the two schemas. I figured this should be a breeze, infer a schema from my existing data (with a few tweaks here and there of course), visually map the old structure to the new, and a wonderfully quick XSLT is born to do my grunt work.
Ooh boy was I wrong....
So what if the old table I was converting had over 250 poorly named columns? So what if the schema it was mapping to was a 1500 line, 100 type monolith? Did I mention it wasn’t my design?
Even taking these depressing facts into consideration the code MapForce produces is nothing short of abysmal. Every single mapping, regardless of the maxOccurs setting for the type in the schema, gets a for-each tag. I much prefer to use templates for the sake of extensibility, readability & modularity etc. Much like a procedural programmer likes subroutines.
However there is another reason for-each irks me, and here is a snippet of the auto-gen to demonstrate:
<xsl:param name="ForwardSlash" select="'/'"/>
<TitleRef>
<xsl:for-each select="titleref">
<xsl:variable name="Vvar24_titleref" select="."/>
<xsl:variable name="Vvar25_INPUT" select="$ForwardSlash"/>
<xsl:variable name="Vvar26_RESULTOF_substringbefore" select="substring-before($Vvar24_titleref, $Vvar25_INPUT)"/>
<TitleVolume>
<xsl:value-of select="$Vvar26_RESULTOF_substringbefore"/>
</TitleVolume>
</xsl:for-each>
<xsl:for-each select="titleref">
<xsl:variable name="Vvar28_titleref" select="."/>
<xsl:variable name="Vvar29_INPUT" select="$ForwardSlash"/>
<xsl:variable name="Vvar30_RESULTOF_substringafter" select="substring-after($Vvar28_titleref, $Vvar29_INPUT)"/>
<TitleFolio>
<xsl:value-of select="$Vvar30_RESULTOF_substringafter"/>
</TitleFolio>
</xsl:for-each>
</TitleRef>
MapForce just gets it all wrong. There will always be a TitleRef tag in the resultant XML, regardless of whether or not the transform encounters the titleref element in the source document. The duplicate for-each tags are partly because I asked something weird of the designer. “Give me the substring before a slash and put it here, and then give me the substring after the slash and put it there”. However I never intended for this monstrosity to occur. All of this pain could have been avoided with the following XSLT:
<xsl:template match="titleref">
<TitleRef>
<TitleVolume>
<xsl:value-of select="substring-before(., '/')"/>
</TitleVolume>
<TitleFolio>
<xsl:value-of select="substring-after(., '/')"/>
</TitleFolio>
</TitleRef>
</xsl:template>
Which is what I had in mind when I was visually designing it in the first place. I guess WYSIWYM is what I really want out of a designer these days.
MapForce is actually quite a nice tool for visually mapping and allows you to map between many different types of data source, using a good variety of modern programming languages (C#, XSLT 2.0) to do so. It exposes a good set of functions for you to use in the process with a neat way of visually representing them.
The Big Problem™ is that while the editor will let you visually design your transform, apparently providing two way communications between designer and transform editor was too hard. That is to say, thou canst see the gen’d code but thou canst edit the gen’d code.
My conclusion is that MapForce is your classic I-don't-want-to-know-what’s-under-the-hood kind of auto-gen tool. I ended up dumping the XSLT into VS2005 and used their excellent XSLT editor to finish off. The new improvements to the XSLT interface have made me migrate back home to Visual Studio.
So……Like most developers, I find myself disenchanted with the extremely poor code that auto-gen code tools espouse. I guess it keeps monkeys like me in a job though.
© Copyright 2008 Jim Burger
|