Given that I haven’t blogged while I was at home, I figured that I should be obtuse and do so while on vacation.  Currently hanging out in sunny Palm Springs, California for a few days.  On Tuesday, March 16th, I’ll be making my way down to the Inland Empire .NET User Group for a quick talk about SOLID.  Then it’s off to Legoland and the San Diego Zoo.  Oh, and somewhere in there I have to work in a trip to the Palm Springs Air Museum.  As a history buff, it’s really cool to see all the WW2 aircraft they have there – some of which are still in working order.

Note:  I am in no way, shape, or form affiliated with HarvestApp.com.

I’ve been an independent consultant in IT for four years now.  One of the biggest things in my day-to-day activities is keeping track of my time.  Timekeeping has become a bit of a thing for me, even when I was an employee.  It probably stems back to about 1996 or so, when my first web application ever was a timesheet application I wrote while working at Alberta Transportation & Utilities (now Alberta Infrastructure).   It was in C++, using Netscape Commerce Server and CGI.  I even had to write my own libraries to parse the HTTP requests and came up with my own crude templating engine.  Yes I’m old.  Yes, it was interesting.  Yes, we have it better now.  No, I would not like to repeat that experience.

Anyway, over the years, I’ve tried many different things, from a VBA solution based on Outlook, Excel spreadsheets, to Timesheet.PHP, to a WebForms app based on the Timesheet.PHP database which I ported over to ASP.NET MVC when I wanted to expand my jQuery and ASP.NET MVC knowledge.  My little home-grown web app was good for what I needed it to do, but it wasn’t anything fancy.  If it was, I’d have sold it and become rich beyond the dreams of avarice.

In the early fall, a friend of mine told me about HarvestApp – a subscription based, online time-tracking application.  Thought I would give it a try.  My thinking at the time was that I’m not really in the business of writing a timesheet application, and I really need to keep track of time – as a consultant, billable hours are pretty important.  So, here I am now, almost six months later, and I will say that I like HarvestApp.  I find it quick, and easy to use.  I get easy to see reports.  You can create invoices (I don’t use HarvestApp to create my invoices, but you could).  You can track expenses.  It’s mobile friendly.  It’s moderately priced (IMHO – YMMV).  It has a public API so you can write your own applications against it. 

Anyway, don’t take my word on it, try it for yourself.

tumbleweedYeah, I’ve been kind of quiet as of late.  So quiet, I suspect that some people might be wondering if something happened.  I was a bit surprised to see that the last time I had blogged was after TechDays in Calgary.  Well, nothing significant has happened – just a bit of laziness augmented by a touch of tech-burnout compounded by the odd bit of single malt scotch.

So, now that one month is almost up on 2010, I figured that it was time to start blogging about something again.  The first trick to this, of course, was to figure out what I wanted to do in 2010.  It does seem like there will be a lot of interesting things, technically speaking, coming up this year.

A couple of new things I want to look at over the remaining 11 months:

Mobile development, particularly with a focus on Androidandroid-robot-logo1.  For the latter half of 2009 I have been dabbling in Android.  I believe that it’s time to go out on a bender, and in a drunken stupor get some embarrassing tattoo and join the Android Army.  So far, I’m at two out of three.  Not bad, huh?

AndroidArmy 

Ruby is another technology I’d like to explore – particularly Rails.  I can help but think that the opinionated view that Rails development has taken is the way to go for the bulk of web development.  A lot of websites are basically just forms over data, and Rails seems to address that concern rather well.  To bad nobody around here in Edmonton does much Rails development.

.NET 4.0 and ASP.NET MVC2.  I know there is a lot of debate between Web Forms and ASP.NET MVC.  Personally, I think MVC is the better way.  Probably best to keep abreast of what is going on in the ASP.NET MVC world.  And, of course, the DLR in .NET will come to maturity soon.  By maturity I mean widespread acceptance.  If this happens, then maybe developers won’t get so hung up on languages:  i.e. “I’m a C# guy so VB.NET sucks”.

And finally, a guy needs hobbies.  Now granted, my past hobbies of alcohol and guns (no, not together at the same time) have served me well for the past 20 years or so. However, they are hard hobbies to share with my sons at this point in time.  So, at the start of winter I expanded the geek factor of my sons (and myself) by getting back into Warhammer.  Now the last time I played was about 20 years ago, with the 3rd edition rules.  In fact, I still have some of the books in my basement from back then.  Anyway, picked up The Battle for Skull Pass boxed set.  My son rather likes the Dwarfs.  I suspect it’s because he’s similar in stature/height to the stunties.  Myself, while I find the Greenskins amusing, I suspect I might have to move on and get serious with Dark Elves.

Anyway, enough for tonight.

Yesterday I was at TechDays 2009 in Calgary for the day (well, the morning really).  I wasn’t there as an attendee, but as a speaker.  Thanks to everybody who came out to my two talks, the first one on an Introduction to ASP.NET MVC and the second one on SOLIDifying your ASP.NET MVC Application.  There were a few hiccups along the way:  as usual, I fell victim to the Technical Presentation Time Dilation Syndrome (i.e. ran out of time) on both talks.  I guess I’m just to long-winded for my own good.  As well, because I was running a EAP of Resharper 5, I had some Visual Studio 2008 issues – namely VS2008 would hang on me from time to time.  Note to self: maybe don’t use the bleeding edge tools in a talk.  And I really should break myself of wanting to type all the code – using snippets would really save me time.

Two things that suprised me:

  1. That there was still that much interest in ASP.NET MVC intro talks.  I just figured that everybody knew/knows about it.  Or maybe I just spend to much time with guys who have drunk the ASP.NET MVC Flavor Aid.  Either way, I think that there were some in the crowd that will convert from WebForms to ASP.NET MVC.
  2. I asked how many people wrote unit tests or developing their software using Test Driven Development was the number of people who didn’t raise their hands.  While I didn’t expect the majority of the crowd, I did expect a lot more people than I saw.  Maybe it was a quiet crowd, and people didn’t feel like saying they wrote unit tests.  Maybe I live in a bubble, and my perception of what is actually going on in the .NET world is skewed (that is to say, perhaps writing tests is the exception rather than the rule).  It did kind of make me a bit concerned, as I truly believe that TDD does help one write better software overall.

Anyway, here’s to hoping that TechDays 2010 will stop off in Edmonton.  And hopefully have a track that will focus on developer fundamentals, like TechDays had in Toronto and Vancouver.

Out of intellectual curiosity, I sparked up MonoDevelop and decided to see what would happen when I tried to compile the ASP.NET MVC source code. I figured that it would Just Work.  After all, I can use the .NET compiled assembly with no problems on Mono, so there really shouldn’t be any problems trying to compile the code.  Bad news is that there is one minor glitch.  Good news is the glitch is easy to work around and has already been fixed so it shouldn’t be a problem for future version of Mono.

When you compile, here is what you get:

Compilation failed: 1 error(s), 0 warnings

/home/tom/Projects/MVC-MS-Pl-original/MVC-MS-Pl/Mvc/FormCollection.cs(25,6): error CS0246: The type or namespace name `FormCollectionBinder’ could not be found. Are you missing a using directive or an assembly reference?

Build complete — 1 error, 0 warnings

So, this kind of surprised me.  Looking at the code, I did see the FormCollectionBinder in the code, it’s an embedded class within System.Web.Mvc.FormCollection, check out lines 68-88 below:

   1: /* **************************************************************************** 
   2:  * 
   3:  * Copyright (c) Microsoft Corporation. All rights reserved. 
   4:  * 
   5:  * This software is subject to the Microsoft Public License (Ms-PL).  
   6:  * A copy of the license can be found in the license.htm file included  
   7:  * in this distribution. 
   8:  * 
   9:  * You must not remove this notice, or any other, from this software. 
  10:  * 
  11:  * ***************************************************************************/ 
  12:  
  13: namespace System.Web.Mvc { 
  14:     using System; 
  15:     using System.Collections.Generic; 
  16:     using System.Collections.Specialized; 
  17:     using System.Diagnostics.CodeAnalysis; 
  18:     using System.Globalization; 
  19:     using System.Web.Mvc.Resources; 
  20:  
  21:     [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", 
  22:         Justification = "It is not anticipated that users will need to serialize this type.")] 
  23:     [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers", 
  24:         Justification = "It is not anticipated that users will call FormCollection.CopyTo().")] 
  25:     [FormCollectionBinder] 
  26:     public class FormCollection : NameValueCollection { 
  27:  
  28:         public FormCollection() { 
  29:         } 
  30:  
  31:         public FormCollection(NameValueCollection collection) { 
  32:             if (collection == null) { 
  33:                 throw new ArgumentNullException("collection"); 
  34:             } 
  35:  
  36:             Add(collection); 
  37:         } 
  38:  
  39:         public IDictionary<string, ValueProviderResult> ToValueProvider() { 
  40:             CultureInfo currentCulture = CultureInfo.CurrentCulture; 
  41:  
  42:             Dictionary<string, ValueProviderResult> dict = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase); 
  43:             string[] keys = AllKeys; 
  44:             foreach (string key in keys) { 
  45:                 string[] rawValue = GetValues(key); 
  46:                 string attemptedValue = this[key]; 
  47:                 ValueProviderResult vpResult = new ValueProviderResult(rawValue, attemptedValue, currentCulture); 
  48:                 dict[key] = vpResult; 
  49:             } 
  50:  
  51:             return dict; 
  52:         } 
  53:  
  54:         public virtual ValueProviderResult GetValue(string name) { 
  55:             if (String.IsNullOrEmpty(name)) { 
  56:                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name"); 
  57:             } 
  58:  
  59:             string[] rawValue = GetValues(name); 
  60:             if (rawValue == null) { 
  61:                 return null; 
  62:             } 
  63:  
  64:             string attemptedValue = this[name]; 
  65:             return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture); 
  66:         } 
  67:  
  68:         private sealed class FormCollectionBinderAttribute : CustomModelBinderAttribute { 
  69:  
  70:             // since the FormCollectionModelBinder.BindModel() method is thread-safe, we only need to keep 
  71:             // a single instance of the binder around 
  72:             private static readonly FormCollectionModelBinder _binder = new FormCollectionModelBinder(); 
  73:  
  74:             public override IModelBinder GetBinder() { 
  75:                 return _binder; 
  76:             } 
  77:  
  78:             // this class is used for generating a FormCollection object 
  79:             private sealed class FormCollectionModelBinder : IModelBinder { 
  80:                 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
  81:                     if (controllerContext == null) { 
  82:                         throw new ArgumentNullException("controllerContext"); 
  83:                     } 
  84:  
  85:                     return new FormCollection(controllerContext.HttpContext.Request.Form); 
  86:                 } 
  87:             } 
  88:         } 
  89:  
  90:     } 
  91: }

The version of Mono 2.4.3 I have doesn’t compile the class FormCollection because the FormCollectionBinderAttribute is inside the FormCollection class.  This is the bug, and it has since been fixed.  Easy ways to get around this:

  1. Just use the binary assembly from Microsoft for ASP.NET MVC.
  2. Build your own Mono with the fix included
  3. Move the code for FormCollectionBinderAttribute class outside of the code for the FormCollection class.

Well, today was a rather sad around the household.  This morning I had to take Bailey, my dog, to the vet to be put down.  She had just turned 14 years old in September of this year, and age had finally caught up with her.  Her hips were going and we were getting concerned that one day she would be stuck on the floor and wouldn’t be able to walk anymore.

Just a heads up that TechDays Canada 2009 is happening in Calgary next week on November 17 and 18.  Yours truly will be there for the whole morning of November 18th talking about ASP.NET MVC and SOLID (note that this is not the same SOLID talk from the DevFundamentals track at TechDays Vancouver and TechDays Toronto).  If you happen to be there, don’t be afraid to come on by and say hello.

These days I mostly boot Linux as my host OS, and then run things inside a VM.  However, one Windows dependency I can’t seem to shake is Windows Live Writer.  It just seems that there isn’t a Linux answer to this – or is there?  Does anybody have a suggestion for a blogging client that a guy could use under Linux, without having to spin up a VM each time?

Update November 10, 2009:  Looked around for a bit, and I was rather disappointed with the current crop of native Linux blogging clients – at least the ones that Ubuntu 9.10 knew about.  I did come across ScribeFire which seems promising.  To quote the website:

ScribeFire is an extension for the Mozilla Firefox Web Browser that integrates with your browser to let you easily post to your blog: you can drag and drop formatted text from pages you are browsing, take notes, and post to your blog.

So far, I like it.

A while ago I picked up a Microsoft Notebook Mouse 5000.  Finally decided to use it on my laptop.  I figured that having a bluetooth mouse would mean that I wouldn’t have a USB receiver hanging off my laptop all the time.  Plus, I thought it would be nice to use Blue Proximity.

Now, the hiccup came when setting up the new mouse on Ubuntu 9.04 64-bit.  It seems that you have to do a little bit extra to get the mouse working. I found the solution on the Ubuntu forums.  For my one selfish purposes, I will repeat the instructions here:

1) install the bluez-compat package with terminal
sudo apt-get install bluez-compat

2)Pair the mouse with the bluetooth manager. The manager will say that the pairing is "successful"
Although the mouse won't worked... this step has to be done...

3) In the terminal, type :

sudo hidd --search

You should see something like

Searching ...
Connecting to device 00:XX:XX:XX:XX:XX (your mouse MAC)

Done. Your mouse should be working now.

Well, don’t let the name of the post fool you – the next EDMUG event is in November, not October,  November 4th, to be exact.  I’ll repeat the e-mail I got with the details:

Date: November 4th
Time: 5:30pm doors open, 6:00pm event starts
Location: Edmonton Room in the Stanley Milner Library
Event Title: Practical Automated Testing Dojo

As we may have eluded to in recent newsletters, we’re going to try some new style events for this year’s schedule.  In the past the lecture presentations that we’ve held have provided great content in an easily accessible format.  They also seem to have left attendees wanting for more practical and hands on exposure to the technology being discussed.  This event will be the first of those new formats that will allow you to get started with that practical experience while still receiving some guidance.

How the Dojo event will work:

At the start of the meeting (6pm in this case) we will provide a brief introduction talk on Automated Testing.  This will take up no more than 15-30 minutes and is not intended to be an in depth review of the practices involved.

After the introduction a number of volunteers who are well versed in Automated Testing will form breakout teams which attendees will be free to choose from.  Those teams will spend the majority of the remaining event time (1.5hrs plus) working through real world examples of how to write automated tests using different tools and different styles.  While there will be one person who can provide guidance, we are encouraging all attendees to spend time pair programming, watching and engaging in questions with the entire group.  Attendees should also feel free to move from one team to another as the content, styles and experiences may be different.

What, you ask, will the attendee be responsible for?  Well, our hope is that you will feel inclined to bring questions about Automated Testing and a desire to interact and learn with and from the rest of the community.  If you can, please bring your own laptop.  There will be some laptops available but they will be used in pair (or more) programming scenarios only. We will be providing a sample code base that needs many different kinds of tests added to it.  If you want the code at the time of the event, please bring a USB drive.  For those that don’t we will provide the code for download from the Edmug website after the event.

As this is our first event of this style, we are going to treat it as a learning experience and apply those lessons to the coming events.  As always, we encourage you to provide us with any feedback that you can at info@edmug.net

The Edmug Team

www.edmug.www

So, with that out of the way, it’s a pretty loosy-goosy format.  If you are going, is there anything in particular that you would like to see or do?  Some code you would like help with?  Need a laptop?  I will be there, and more than willing to help out with your questions and figured that it can’t hurt to find out in advance some specifics.  Feel free to respond to me either via comments here, or by e-mail (tom at opgenorth dot net).