Subscribe
Sign In
|
 Thursday, June 21, 2007
Well, I bumped into an interesting build error this afternoon, one I hadn't seen before:
Could not find file 'Microsoft.Windows.CommonLanguageRuntime version=2.0.50727.0'
For reasons I shan't go into here I write production code in VB .NET, however for unit tests I write in C#. This obviously results in mixed language solutions. The error occurs when I reference a VB windows app project in my C# test project using a project reference. This windows project is also published via ClickOnce. According to this knowledge base article the solution is quite simple: use a file reference. Obviously, as I found out, this issue is not restricted to VB projects referencing VB projects; C# projects that reference VB projects are at risk too.
The word out on the street is that you can also work around this by turning off ClickOnce security settings on the project being referenced, which wasn't an option for me. It's important to note that this issue is not intended behaviour, and we can expect a fix in the next version of Visual Studio, codename Orcas.
I'll admit that project references can be problematic, although for the most part they work well at my workplace, but be wary if you are project referencing ClickOnce apps, and don't think you are completely immune if you use C# either.
This may not be news to some of you, and for you I apologize. For the rest, please avoid using MsgBox in VB .NET projects, and use MessageBox.Show instead.
MsgBox is a wrapper around the MessageBox.Show method and is meant for backwards compatibility with older VB projects. It should be left for those who really can't do without it.
A common misuse for message boxes is debugging code, and most people have invariably found the following code snippet lazing about in production code from time to time:
Try 'Some error prone code Catch ex as SomeException MsgBox(ex) End Try
The problem with this 'debugging' code is that in certain circumstances it will cause bugs of its own. Beware of MsgBox throwing exceptions. I'm not referring to just the documented InvalidOperationExceptions either. If the exception does something interesting in its overload of ToString, or if the MsgBox function fails when determining the title of the message box then anything from StackOverFlowExceptions to OutOfMemoryExceptions can occur.
But wait…..there's more, another issue is localisation. If you are using FxCop and have turned on System.Globalization, any call to MessageBox.Show must specify the RTL nature of the box to be shown. The problem with MsgBox is that while it does some fancy work to determine the title, it doesn't bother determining the RTL nature of the parent window. The CA rule doesn't appear to have been written to take calls to MsgBox into consideration. In short, calls to MsgBox break the Globalisation rule CA1300.
In my previous post I described how using some readily available tools and some simple conventions for work item creation can equip yourself with some excellent information about how your team works. In this post I intend to explore some of the custom queries that I have been asked to create in day to day life as a TFS consumer.
One such request was for a query that will tell you, of all the work items you have delegated to others, which ones are outstanding. To achieve this follow these steps to create a TFS query. Having done that you will want to provide the following filters:
- Team Project = @Project
- AND Created By = @Me
- AND Assigned To <> @Me
- AND State = Active
- AND Area Path Under <AreaPath>
- AND Iteration Path Under <IterationPath>
By changing the "AND State = Active" to be "AND State <> Active" one could query the completed and closed tasks. Optionally you could filter out Scenarios using the 'Work Item Type' field. Don't forget that team explorer can easily dump into and out of Excel which can be handy if you need an earbashing list. The query options straight out of the box are 'good enough' for most situations, and you don't have to write any code if that's not your thing.
For those of you wanting a little more than a simple query, e.g. you want parameterisation, I did find that creating your own TFS reports was a reasonably straight forward experience as well. The first thing to do is to create a report model on the TFS warehouse objects (TfsReportDS and TfsOlapReportDS by default). TfsOlapReportDS points to a SQL Analysis Services cube which the standard reports all use. One can spend more than a few hours just looking around in there, so consider yourself warned ;)
Creating the report model is easy enough, just browse to your TFS Sharepoint portal, and find the link to your Report server web interface (typically http://TFSServerName/Reports) and click on the TfsOlapReportDS of TfsReportDS link (the docs say you should favour the TfsOlapReportDS for reporting). Once there you can hit the generate model button and have it generate a reporting model for you. Then just click the link to report builder and start going nuts. I whipped up a non-parameterised report in under an hour that distilled the check-in history of an Area to look like an activity report, using all the wonderful comments our team had provided on each check-in, as a result of the check in policy.

As you can see I pulled in the change set details, the number of lines changed. Using a quick function on the max and min check in date would show how long the entire project took at a glance. Obvious improvements to this would be grouping by scenario and iteration. This report was brought to you courtesy of the Code Churn entity, which is useful for more than just this simple activity report. You can use code churn to ascertain the quality of your code as well.
By using the report designer in Visual Studio, you can start leveraging your SQL skills (of which I have very little) to create more elaborate reports, although I think I shall leave that as an exercise for the reader, rather than going into it here as the principle is largely the same. For further information on using the report services I can highly recommend Bob Meyers SQL Reporting Services blog and a book by Paul Turley, Todd Bryant, James Counihan, Dave DuVarney entitled Professional SQL Server 2005 Reporting Services for those who don't mind reading after a hard days coding.
In summary, developers often concentrate on making sure that each line they write is well crafted, and that's a good thing, so why not make check in time another opportunity to be efficient and useful instead of an inconvenience? There are benefits for developers and project leaders alike, and the key to finding those benefits is by having good data collected at check in time. The analysis tools provided by TFS are powerful enough to satisfy most needs, and if a SQL neophyte like me can whip up a semi-useful report in an hour, imagine what a SQL Jedi could achieve?
 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.
© Copyright 2008 Jim Burger
|