Sunday, May 27, 2007

DataSet Diagrams

We often use Strongly-Typed DataSets in our applications at work. They can be a useful tool but they have their limitations too. Today, I'm not going to discuss the pros and cons of DataSets versus some other DAL concept. Today I'm just writing about a useful tip for working with growing DataSets.

As changes are made to tables and relationships in the DataSet Designer, eventually all the diagrams become unordered and relationship links begin to wander like vines. Unfortunately, I have never been able to find in Visual Studio an option to re-layout the diagram automatically for optimum table sizes and minimum relationship intersections. You don't have to shuffle them around manually though, there is another way:

  1. Open the project containing the DataSet and Show All Files in the Solution Explorer.
  2. Ensure the DataSet designer windows are closed.
  3. Open the DataSet's .XSS file in a code window (it should be XML with <Shape> elements among others).
  4. Clear the entire contents of the XSS file, leaving it blank.
  5. Save the XSS file and close the window.
  6. Open the DataSet's designer window, you should find all the tables and relationships nicely arranged.

It's been a busy day but I should have another overly long post ready in time for next week.

 Saturday, May 19, 2007

The Diet Coke Of Unit Testing?

I have been wanting to make use of Unit Testing in my personal projects and my projects at work. So far I've read a lot about unit testing concepts and implementations and even written a few tests to get a feel for it. The majority of the material that exists about unit testing in .NET refers to the NUnit testing framework. The is presumably because it was one of the first .NET unit testing frameworks and based on the well established JUnit. However, now that Visual Studio 2005 includes it's own unit testing framework, why wouldn't you want to use that?

Jean-Paul Boodhoo once blogged1 that when a new developer joins your team they should be able to Get Latest from source control, build, and be ready to work. I agree and using tools included in Visual Studio means one less dependency for a new developer to install on their workstation. However, there is the possibility that Visual Studio's Unit Testing, as a version 1.0 product, might be lacking important functionality to be found in established testing tools. A quick Google for "visual studio unit testing vs nunit" leads to a few notable issues.

Jason Anderson explains that only Visual Studio Team Suite includes the Unit Testing tools and that Visual Studio Professional misses out. We all use Team Suite at work so this isn't a problem but I can understand that unit testing should be available developers in all team sizes. Thankfully, Naysawn Naderi says that we can expect Unit Testing in Visual Studio Pro when Orcas is released.

Roy Osherove also has two posts about choosing between Visual Studio Unit Testing and the alternatives. Roy's comments makes VS Unit Testing seem completely useless and claims some parts are broken and even says "how this one went by into the release is a mystery to me". However, I recently had the pleasure of working with VS Unit Testing briefly when contributing to the BlogML project and some of Roy's claims just felt wrong. Surely it can't be that bad. Considering we will want to decide on a testing framework for projects at work soon, I decided to verify these problems.

Roy's first complaint is that there is a bug with the ExpectedException Attribute checking the type of the Exception only and not checking the Message. This is in fact a misinterpretation of the VS Unit Testing ExpectedException Attribute and assuming it was designed the same as NUnit's counterpart. NUnit takes an Exception type and message and verifies that the right Exception is thrown and that is has the matching message. VS treats the message parameter that same as an Assert statement and uses it as the display message to the user when the test fails, admittedly the MSDN documentation is very poorly worded. However, achieving the same behaviour as NUnit is often desired and there is a quick solution:

[TestMethod()]
[ExpectedException(typeof(InvalidOperationException))]
public void ExceptionWithMessage()
{
    try
    {
        MethodToTest();
    }
    catch (InvalidOperationException ex)
    {
        Assert.AreEqual("Expected message.", ex.Message);
        throw;
    }
}

Roy is also disappointed that ExpectedException doesn't work with the base Exception type. Sure it's something the unit testing framework doesn't support but you shouldn't be throwing Exception objects and you shouldn't be catching them either. You can also use the Test Results window to group by Result (ie Passed/Failed), Class Name, and Full Class Name (ie Namespace too), this makes locating the tests your interested in much easier and also negates Roy's corresponding observations with regard to Test Driven Development.

VS Unit Testing isn't perfect though and that's to be expected for a first release. As Roy points out, you can't easily get to the failing production code from a failed test result, it doesn't have quite as many included Asserts as NUnit does and you do need to have Visual Studio installed to use the MSTest command line test runner. For the time being, our requirements don't push VS beyond it's capabilities, Orcas should improve on the weaker points when it's released later this year (?) and it is really easy to convert between NUnit and VS Unit Testing if we need to.

So, if you're looking to choose a unit testing framework, don't be put off by some of the articles flying around about VS. Give NUnit and VS Unit Testing a go and maybe MbUnit and some of the others too. Ultimately you'll find something that you and the rest of your team are comfortable with and fits your process. I can't say that any of them are perfect, nor are any flawed beyond useful. And, if you've managed to read this entire post, thanks for putting up with my ramblings ;).


1. Update: Added link to Jean-Paul Boodhoo's article.

kick it on DotNetKicks.com

 Tuesday, May 15, 2007

Speed Limits

Just a quick update today. I read in my ISP's newsletter about a new group promoting quality broadband in Australia, T4. It's good to see some big names behind the movement.

In Australia, I'm among the lucky minority with access to an ADSL2 Internet connection. While ADSL2 can potentially provide 24000Kbps downstream and 1000Kbps upstream, due to my line quality and the distance from the exchange I'm currently only getting 5568/864. However, I am paying $69.95 per month for the privilege and if I download more than 40gb my connection is slowed to 64Kbps for the remainder of the month. Compared to Scott Hanselman's guaranteed 15000Kbps/2000Kbps Internet connection for only US$50.00 per month my broadband is rather poor and from what I can gather Hanselman doesn't have a download limit.

Unfortunately, as I mentioned before, I'm among the lucky minority. Many users only have access to ADSL1 1500/256 connections and pay more than I do. Even more users, including some of my company's clients, can't get any better than dial-up or 64Kbps ISDN connections. These connections are unbearable to use VPNs or Remote Desktop to perform upgrades or maintenance.

Admittedly the sparse nature of the Australian population introduces some technical barriers and additional costs that Japan, the United States, and other better connected countries don't have to deal with, but groups like T4 and G9 have shown they are not insurmountable and will not cost as much as Telstra will have us believe.

 Saturday, May 12, 2007

It Seems To Go On And On Forever

Those people with too much cash can now buy 1000GB 3.5" hard drives and 200GB 2.5" hard drives and the slightly smaller models are available at very affordable prices for the rest of us. With so much storage capacity available and so much data and information being produced everyday we should be filling our hard drives as fast as the manufacturers can build them. But aside from the torrent leeches, there seems to be a large number of computer users with a conflicting combination of ample free space and insufficient backups. When the average computer user buys a new machine with hundreds of gigabytes of storage, which never sees more than 30% utilization, and still manages to lose an important email or accidentally overwrite their holiday photo collection you have to start thinking that something isn't right.

The computer industry started it's life in a world of limited memory and limited processing power. At every opportunity low level optimizations were made to wring the most out of every instruction cycle and squeeze the most into every data bit. At the time it was necessary and it generated some great concepts and algorithms that still apply today, but it causes many problems too. The most infamous example is the Y2K bug. We squeezed years into two digits (or even less) because it was all we needed and all we could afford but as technology improved and became more accessible, the methods didn't keep pace. The same ideas behind using the least bits for date storage are still applied to storage in general.

The tasks we perform on our computers daily require the user to take responsibility for deciding what files they would like to save, which revisions of a document should be tracked, and how big their Internet files cache and Recycle Bin should be. This is an approach which is important where storage is limited. However, with gigabytes galore to spare my computer should save every file I touch, track every revision of every document, keep every web page I ever visit and shouldn't even bother me with the idea of deleting something let alone the concept of a Recycle Bin. Of course, I'm not the first person to realise this, and we are slowly beginning to see it in action today.

Vista is using the Volume Shadow Copy system to provide previous file versions to all users via easy menus in Windows Explorer and Common File Dialogs. I understand Mac OSX has been doing something very similar too. Microsoft has a new Home Server product in beta designed to completely backup all machines on a small network and allowing the user to restore to any point in time. Red-Gate SQL Compare, one of my essential tools, just saves any comparison project you create and doesn't even bother you to choose a location. I'm sure there are many other examples I can't think of right now and many more I haven't seen.

Next time you are building software think about how it is handling its data. Does it require the user to explicitly save? Does it discard data or keep it by default? If it changes data does it store the data as it was before the change? What would be involved to change the default behaviour to keep everything? In all but the most trivial cases it gets quite complicated. At the most basic level you need to decide how to store all this extra information. You then need to give the user the ability to find and retrieve what they want from the increasing hoard of information. And eventually, when you store everything and you start running out of space, you need to decide which data is no longer required and you need to decide whether to delete it, archive it to offline storage, or insist the user install another hard drive.

Ultimately many of these issues will best be solved by the underlying architecture and different approaches will need to be used for company documents versus files in the Internet cache. I imagine there is some very interesting research going into these problems and I look forward to the systems of the future where I don't have to worry about losing that family photo or overwriting my budget plan. If you know of any software that is already taking the keep everything approach, or you are building a system yourself that will do just that, leave a comment, I'd be fascinated to read about your experiences.

Now, if only I could remember where I saved that article about temporal databases...

 Sunday, May 06, 2007

Preaching To The Converter

During the past week I have managed to transfer my posts from my Live Space to this new Das Blog site. It was pleasantly trouble free, due mostly to the hard work having been already done by the BlogML team.

The biggest headache was the limitation of the Live Space MetaWeblog API implementation. The API will only allow you to retrieve the most recent 20 posts or, if you know the postId, one post at a time. Unfortunately there is no supported method for retrieving the postIds beyond the most recent 20.

Luckily, upon inspection of the nature of the postIds on my Live Space, and inspection of the Live Space Team's blog for confirmation, I discovered a predictable pattern to the postId. It consists of a unique hex string for the space, and an exclamation mark followed by a decimal number that increments with each new post.

With this information I was able to write a Live Space to BlogML converter that, while not exhibiting amazing performance, is able to retrieve all posts on a Live Space much easier than doing it manually or by screen-scraping.

My currently one-way Live Space converter is available in ChangeSet 21935 and later of the BlogML project on CodePlex. Hopefully the project coordinators will build a new release soon and it will then be available as part of the main package.

To use the converter, start by enabling email publishing on your Live Space. Then create a new Visual Studio project and reference the LiveSpace.BlogML assembly. Construct an instance of the LiveSpaceBlogMLWriter passing the name of your Live Space and your email publishing secret word. Optionally set the PostCount property to a number ideally no greater than the number of posts on your site. Finally, call the Write method passing a preconfigured XmlWriter as the destination.

Please submit any issues you have with the converter to the BlogML Discussion pages and I'll endeavour to solve them. For those without the resources or inclination to write a program as mentioned above, let me know and I'll find some time to create a user interface for it.

UPDATE: Doron Yaacoby has created a GUI for the Live Space BlogML converter.

 Saturday, April 28, 2007

Welcome

Welcome to my new blog domain.

I recently decided that I would commit to a more regular blogging schedule. I've kept to my plan for three weeks so far and decided I wanted some more control over my blog than Live Spaces would allow. This site is the result.

There may be lull in the posts while I investigate the Live Spaces MetaWeblog API to export my old posts at Jason's Thoughts to BlogML then import them to this new site. Hopefully it won't be very long at all and will generate some material worth blogging in the process.

In the mean time, links to my scattering of other content is in the Navigation side bar and I highly recommend my favourite bloggers listed in the Blogroll sidebar.

 Sunday, April 22, 2007

The Horse That Will Not Die

I am a VB.NET developer, I have been for a long time thanks to my background with old VB3 and BASIC before that. However, I like C# and I use it whenever an opportunity arises but due to business requirements the primary language with both my last employer and my current employer is VB.NET. It shouldn't matter much though because, due to IL, the Framework library and the Common Language Runtime, both VB.NET and C# compile down to very similar results.

Sadly, the VB.NET developers experience differs from the C# developers experience even though they now share the same IDE. It seems more and more regularly that I find myself making the comment to my colleagues at work that some particular issue would be easier to deal with if we were using C#. Here are some that come to mind:

C# has the ternary operator (<condition> ? <trueresult> : <falseresult>). This is a minor difference but can simplify some otherwise verbose code. VB.NET has the IIF function but it always returns Object instead of the type of the result, thereby requiring a cast, and it is not short-circuited, making it less effective at avoiding NullReferenceExceptions. Apparently, in Orcas, the IIF function gets the same behaviour as C#'s ternary operator.

C# has automated refactoring included. Thankfully, Microsoft arranged for DevExpress to provide a free version of Refactor! for VB.NET so we don't miss out completely. Unfortunately, it doesn't completely bridge the gap. A notable omission is the "Generate Method Stub" refactor that C# includes.

At work, we are slowly adopting Unit Testing where we can to help detect issues sooner in the development cycle. Exposing your production code for unit testing also helps to refactor it for better maintainability. Sometimes you can't easily test internal code but luckily the framework includes the  InternalsVisibleToAttribute which can allow a separate (unit testing) project to call Friend/Internal methods in another project. You can apply this attribute to any VB or C# code but only the C# compiler looks for it meaning we would need to write our unit tests in C#. Again, apparently Orcas has updated the VB compiler to fully support this attribute to.

As well as adopting Unit Testing, we are trying to establish a Continuous Integration system to discover the full impact of changes as they are checked-in. Unfortunately, while the VB IDE is smart enough to infer references beyond the first level, the MsBuild tool used by most CI systems does not, and therefore all builds fail. We could manually add the second level references to each of our projects but any well-meaning developer who uses the Remove Unused References button will undo the hard work. C# requires the second level references to be specified for even the IDE build so it doesn't have this issue. Apparently Orcas changes the VB IDE behaviour to match C# and MsBuild.

VB doesn't completely lose out though. VB has background compilation which makes on-the-fly error detection and Intellisense much more productive. It can slow things down in large solutions and it tends to be the cause of most of the IDE's crashes but in C#, where there is no background compiling, it is sorely missed.

In Visual Studio 2003, VB was behind C# in other ways. The VB team at Microsoft ensured VB received all the missing bits in Visual Studio 2005, however the C# team bounded forward with even more features for C#, thereby still leaving VB behind. With Orcas in Beta 1, we can see that VB has caught up again with the features C# already had. And once again, C# in Orcas has even newer features.

No Sir, I don't like it.

 Friday, April 13, 2007

Where's The Kaboom?

My new home office machine has arrived and I am setting myself up for the most pain possible with my chosen configuration. Firstly I am installing Visual Studio 2005 on Vista Business Edition. Microsoft has only just released a patch for Visual Studio on Vista and it isn't perfect. Add to that running as a restricted user in Vista which introduces more problems. Finally I've chosen the 64-bit edition of Vista which complicates working with Visual Studio and software in general.

Reading the many articles and forum posts about problems with Vista and 64-bit will discourage most people from trying but so far I've found the experience to be quite pleasant. The first road-block is the need for new Vista 64-bit signed hardware drivers but Windows detected everything but the onboard sound and I was able to very easily find drivers on the HP web site for that. Two vital utilities, Daemon Tools and UltraMon, are already available with Vista x64 versions.

Vista has streamlined .zip file handling so I don't need any archiving software and the usual problems with new OS burning software are gone because Vista writes to CD and DVD out of the box. The small problem of burning disc images is solved by the free ISO Recorder, updated for Vista x64. I don't need MakeMeAdmin anymore because Vista's UAC temporary privilege elevation features have solved the problem. And, of course, Microsoft Office works beautifully.

I could rant for hours about the wonders of this new system but there were some issues. I managed to crash Visual Studio while setting the options for the first time but this is an easily avoidable documented issue (thanks Jim). I upgraded SQL Server 2005 to SP2 via Vista's built in AutoUpdate tool so I needed to run the User Provisioning Tool manually afterward to be able to connect. Also, a minor annoyance, Windows x64 has a separate Program Files folder for 32-bit and 64-bit applications and some installers were defaulting to the wrong folder.

I'm keeping a list of issues I encounter with Windows in general and developing with Visual Studio and SQL Server. I'll write about my experiences further on this blog as time passes and as I start pushing the boundaries of compatibility. At this point I have no regrets moving to Vista and 64-bit. I sure don't want to go back to either 32-bit or Windows XP and I'd recommend anyone with similar needs to my own to do the same.