The blog of Tobin

Tobins nerd blog on .NET, Software, Tech and Nice Shiny Gadgets.

Tuesday, November 21, 2006

Use Cases Anyone?...

I've been doing sofware commercially since I graduated in the year 2000, and I've never lost my admiration of Use Cases.

The Sofware Engineering course showed me a lot of doors: UML, MDA, SSADM, DFDs, ERDs, you name it... At one point I remember reading Alistair Cockburns book "Writing Effective Use Cases". It opened my eyes. I thought use cases were little pictures in a UML diagram, and he taught me that there was much more to them than that.

If you've not got into Use Cases, I suggest you take a good look (or a peek, at least).

What they effectively give you is a method for gathering requirements. They encourage you to approach the system from the viewpoint of those people that will interact with your software. They give you a way of organising your requirements in a fashion that suits you - as loose, rigid, simple or detailed as you like. I shouldn't underestimate the word simple there, use cases can be extremely bare-bones (1-2 lines of text) if you wish and still provide much value.

By the end of a very brief use case iteration you should have ring-fenced exactly what capabilities your software will and will not provide. You'll also know every job-role that's gonna be using the solution, what other external systems your interacting with such as ERPs, MS Office Programs, Flat Files, anything non-human basically that plays a part. Finally, if you're willing to leave the technical world you can also elicit what the executives wish to get out of it from a business perspecive (actually, this is crucial IMHO). A brief use case iteration can certainly reveal a lot of things you might not have thought to ask.

This brief iteration might leave you with a use case specification with many many gaping holes. You'll be thinking "I wander what exactly this bit of the software needs to do", Now that you can see these holes you can make sensible decision as to whether the you need to warrant spending more inception time working out the muddy details. After all, hopefully the client is a phone call away... This is a good position to be in.

Despite my like for use cases, I don't come across too many folk in the industry that use them. I'm all for wireframes, site-maps, CRUD matrices and "the software is the specification", but it's weird how so many seem to have missed out.

Is anyone out there using Use Cases? Anyone moved on to better things?

SHAMELESS PLUG - I was considering publishing or selling a variety of example use case documents, which would be based on those that were developed for real projects of budget s ranging from £1K to £50K. The idea being that, if anyone is intersted in learning from real working use cases for real projects, then these would be ideal. If anyone is interested let me know. My plan would be to carefully doctor the real use cases so that they still retain that real feel, but are based on ficticious requirements.

Labels: , ,

.NET 2.0 Got Better with Dynamic Dispatching

Ok, I'm behind the times. Despite using .NET 2.0 on a few small projects, I've not fully got into all the c# language improvements for .NET 2.0 yet.

However, today I was very pleasantly surprised to find that this works...

public void SayIt(String aString)
{
Console.WriteLine("I got a string {0}", aString);
}

public void SayIt(int anInt)
{
Console.WriteLine("I got a interesting int {0}", anInt);
}

public void SayIt(object anObject)
{
Console.WriteLine("I didn't get anything in particular, but it looks like this: {0}", anObject.ToString() );
}

SayIt("Hello"); // outputs "I got a string Hello"
SayIt(2); //outputs "I got an interesting int 2"
SayIt(new System.Net.Cookie("lastLoggedIn","01-Jan-2006"));// outputs "I didn't get anything in particular, but it looks like this: lastLoggedIn=01-Jan-2006"


This is cool stuff - it's called Dynamic Dispatching, and it makes solving certain problems much easier. For example, if you've ever tried to use the Visitor pattern in .NET, you'll know what I mean: dynamic dispatching lets you set up handlers for each node type in the heirarchy without using statements such as if(node is string){...}else if(node is Cookie){...}.

Similarly, I recall trying to set up some kind of multicast pattern in .NET, but being stumped (I learnt about this in the Pattern Hatching book). The new addition of Dynamic Dispatching should allow recievers to be set up quite easily, interesting stuff indeed!...

This is all good, I'm looking forward to checking out c# v2 a little more.

If anyone knows any good books/sites that hightlight all the new language features, then I'm all ears! For anyone who's interested, I found the dotnetcat.com site seemed to show a few cool new capabilities in concise format.

Labels: , ,

Thursday, September 28, 2006

Jason Fried on Browsers

Jason Fried's comments at the MIT Emerging Techologies Conference make a fair point. The browser is a good platform as long as browser manufacturers don't keep making life hard for web app publishers.

From a user perspective it's desirable not to have to install separate applications for apps such as Flickr and Basecamp.

I still think things will get a lot better as browsers improve and creating richer GUIs gets easier for the developer.

One thing I was thinking is that it would be handy to have a single point of sign on when you open the browser. The browser then passes relevant username/passwords to any sites that require them. Having to remember usernames/logins for every site is still an obstacle that hinders the simplicity of browser based applications. If a single mechanism could address the problem in one sweep, it would make life easier for users.

Microsoft Passport and "remember me" cookies are a step forward, but I think things could be improved if there were a standard that the browser inherently supported.

Friday, September 15, 2006

Parsing HTML and XHTML in .NET

Bear™ says:
know of any good .NET xhtml parsers that are free?

Bear™ says:
something that will correct tags on the fly

Bear™ says:
like;
myString = HTMLParser.Parse ( mySource )

Tobelerone says:
SgmlReader - use it alot and is good.
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=B90FDDCE-E60D-43F8-A5C4-C3BD760564BC

Html Agility Pack - is good too
http://sharptoolbox.com/tools/html-agility-pack

Devcomponents HtmlDocument - very good (I use it too) but costs $99
http://www.devcomponents.com/htmldoc/download.html

Chilkat HtmlToXml - haven't used but buying soon!
http://www.chilkatsoft.com/HtmlToXmlDotNet.asp

Bear™ says:
wow

Bear™ says:
thanks!

Using components that convert HTML to XHTML/XML is a great way to go if you need to mine information from web documents.

The best part of these converters is that they take badly written HTML (with broken tags etc) and fix it up as best they can, so you get a well formed XML document which you can work with.
This then lets you do lovely things such as:


//find all link tags on a web page
XmlNodeList linkNodes = xmlDoc.SelectNodes("//a[@href]");


//find all heading tags on a page
XmlNodeList headingNodes = xmlDoc.SelectNodes("//h1 or h2 or h3 or h4");


Good eh!

Friday, August 11, 2006

200Mbs Network Through Your Mains Sockets

I'm one of the unfortunate people who is useless at D.I.Y. I'm also unfortunate because my ADSL line was installed in the most useless place in the house and I'm incapable of sorting it out. (think hallway, near none of the rooms where I use a computer).

Rather than rip up floors, drill holes, or trail CAT5 cables throughout the house, I decided to invest in WiFi gear. It's pretty good, I just keep my router/wifi bridge and NAS gear in a small cabinet near the ADSL point. Then, all my PCs etc are wi-fi enabled, so no wires needed.

However, sometimes the WiFi is a bit slow, and I was thinking that I'd like my office computers to at least be able to talk to each other very quickly, rather than having to bounce singals through the WiFi access point.

My first thought was to stick another hub in the office, and have all the computers wired through the hub in that room. That way they can all talk to each other quickly. However, they'd be iscolated from the WiFi network, so to get around this I could also plug a WiFi bridge into the hub to relay the signal from the main WiFi access point. Would this work? Can't see why not, but then 4 computers in my office would be sharing one 54Mbs WiFi link.

I was reading around, and stumbled upon an option I'd not considered. Basically, technology exists that allows you to use your mains electricity wiring for network traffic. This stuff isn't new, but it looks like the manufacturers have been busy and started to really make the technology usable. Apparently you can get a 200Mbs unit these days, which is fairly fantastico! Actually, these things only realistically transfer around 60Mbs, but this is still a tad faster than your average WiFi network according to some folk and a review!

If you ever trust Amazon.co.uk reviews, these products got 5 stars from all users!

In case you want to look further into these products, try googling for BPL or Broadband over Power Line products.

Netgear claim to have one that gives a whopping 200Mbs! I think I might have to invest, sounds great...

Sunday, August 06, 2006

Write Cleaner and Clearer ASP.NET Session Code

I recently worked on an ASP.NET project where the original developer had made quite a lot of use of the session. There was lots of code like this:

if not Session("userid") is nothing then ...

if not Session("userid") = "" then ...

if Session("customertype") = 2 then
discountedPrice = price - (price * Session("discount")/100)
end if

The project was reasonably small and I wasn't hired to clean code. However, there's a number of problems with this code that make life difficult, so I wanted to improve things a little.

Don't Repeat Yourself
Firstly, we've got some business logic repeated all over the site. The developer is using the

if Session("userid") = "" then ...

to check to see if the user is logged in. He's also used different variations of this rule on different pages, such as

if Session("userid") is Nothing then ...

This is messy, inconsistant, and in violation of the great Don't Repeat Yourself (DRY) principle. A better way is this:

if not SessionHelper.IsUserLoggedIn then ....

To make this work you need to make a class called SessionHelper that contains static methods for all the logic you need.

'''
''' Creates a handy wrapper for accessing session variables in a clear way.
'''

Public Class SessionHelper
public shared readonly property get IsLoggedIn as Boolean
get
if Session("userid") is nothing
return false
else if Session("userid") = String.Empty
return false
end if
end get
end property
End Class

I think that it's much clearer, and if we want to change our "IsLoggedIn" rule, we only have to do it in one place.

You may be wandering why the developer didn't use .NETs Forms Authentication for this application, rather than the session. I'm not quite sure why to be honest!

Purpose of Code is Not Clear

Consider this line:

if Session("customertype") = 2 then ...

We've got a couple of problems here. The first is a magic number - 2. Any new developer to the project will have to dig around to find out what "2" means, which wastes his or her time. A cleaner way is this:

Dim TRADE_CUSTOMER as long = 2
if Session("customertype") = TRADE_CUSTOMER then ...

You could even define it as a const somewhere so that it's available to all pages and code-behinds.

Note that in the Refactoring book (Martin Fowler), this refactoring is called "Introduce Explaining Variable". In case you've not come across refactorings, they're basically little rules you can use to clean up smelly code. See www.refactoring.com

An further improvement to that might be this

if Session("customertype") = CustomerTypes.TradeCustomer then ...

Here an Enum is used to represent customer types:

Public Enum CustomerTypes
UnknownCustomer = 0
RetailCustomer = 1
TradeCustomer = 2
End Enum

Using the SessionHelper, we could do one final improvement which is this.

if SessionHelper.CustomerType = CustomerTypes.TradeCustomer then ...

which is clearer still.

You may have guessed that I subscribe to the belief that code is something that should usually be expressive and clear. I've not come across many projects where the code doesn't require modifying and changing over time, therefore clarity can drastically affect how easy it is to change.

Think of it this way, every time you write some code you can chose how much time and money it should cost to maintain. If the block of code is going to be thrown away soon, then it may make sense not to invest too much time making it maintainable. However, if you anticipate returning to a block of code a lot then it would save you much time to make it highly maintainable. Also, once you practice writing cleaner code it tends to come more naturally (that said, I still make the odd dogs dinner despite best intentions!)

Some other thoughts
One thing I considered when working on this project was weather to stop storing so much stuff in the session. The session is great because it's easy to access, but there are a couple of downfalls.

The longer some data is in the session, the more stale it gets. If some back office staff update the customer record whilst the customer is browsing the site, the customer won't see these changes until he next logs in. Not the end of the world, but I'd be inclined to work around these problems by default.

One such work around would be to only load the customer data from the database when it's needed. It means more database hits, but that's better than some of the hazards that can arise by having stale data sat around. The principle of caching also states that you should cached data to get cheap access to data that requires frequent access. If we needed to show a username on every page, then caching it in the session may make more sense than pulling it out of the database on every page.

Saturday, August 05, 2006

A Year with the iMate Jam (or MDA Compact)

My MDA Compact (iMate Jam) is beaten, bashed, scratched and dog-eared. The reflective surface of the self-portrait mirror and the flawless shiny paint have faded away through 18 months of constant use. This has been a brilliant PDA phone.

I'm now on the market for a new one, so I thought I'd share my opinion of this thing before it get's retired.

The Good
Small Size - It's just about small enough to go anywhere. I routinely take it to the pub in my jeans pocket, and have never felt like it's a real burdon. However, as I mention in "The Bad", I'd love em to shave .5 cm off it's dimenions.

Runs Great Applications - I've installed all sorts on it over the last year, from Guitar Tuning software to Tom Tom GPS software. The fact that I can use it with a GPS receive and Tom Tom is simply fantastic. This is one of my primary uses for the phone. I've even got the Lanzarote maps so I could get to my dads house from the airport.

Touch Screen - Love it, wish that all phones had one.

Synchronises with Exchange - I host my email with 1and1.co.uk, using their £5 a month Exchange hosting that means all my contacts and calendar are backed up constantly. The fact that my Jam connects to this is great. The other day I dropped my Jam and the battery disconnected. By the time I'd put it back in, the memory was totally reset meaning all my contacts and stuff had been lost. No problemo. I just turned the phone on, entered the Exchange server details, and it was all synced back up in no time.


The Bad

Size - It needs to be a tiny tiny bit smaller. 0.5 cm would do of width, height and length. I find that my jeans pockets are slightly full when going out with a packet of ciggies, some keys, card wallet and the Jam. That said, the sensible thing to do would be to give up the smokes to make more room for technology.

Small Screen - I think that the screen size needs to be bigger to make it better or reading documents and stuff. One day they'll be able to lose the "border" around the screen and give it an extra 1cm in width and height, that would be great. An improved screen res would also solve this problem.

Camera - Ask anyone, the Jam camera is a bit sucky, and there's no flash.

Failed Trials
When I first bought the phone I also bought some accessories. None of them got used for more than a month.

The first was one of those skins to protect the phone. Despite being very snug, it just attracted pocket fuzz and kept falling off. I decided the phone was gonna get beaten up in the long run, therefore gave in to it and threw the skin away.

The 2nd was the Sandisk WiFi card. It was too much of a faff carrying it around, mainly because it protrueded out of the top of the phone. And besides, the phone didn't make a great web browser in my opinion.

Conclusion
This phone is 5 things to me, in this order. It does all of them very well.

#1 - A phone
#2 - A contact & calendar database
#3 - A list of reference material (I keep all my reference data in Outlook/Exchange Notes)
#4 - A GPS navigator

I occassionaly use the other features, such as web browser and document reader, but I still find the thing to small to be or real use in these areas.

I think that I'll replace it with 3 devices. The first will be a nice small smart phone with Exchange capabilities, possibly the Orange SPV C600 (another HTC model), and I'll get one that comes with a free NavMan or something to get the GPS functionality. The 2nd will be an UltraMobile Tablet PC such as Samsung Q1 or the Sony UX180P. Ideally there'd be a cheap one of these that I could use simply as a portable web browser/document reader for under £200, we'll see what I find...

Note that I had considered the Jamin and the Orange SPV M3600i, however, having looked at how I've used the Jam over the last year, the features that I like the most are available on a smartphone (except the touch screen :-( )

Saturday, July 29, 2006

SQL Tricks

There's a lot you can do with SQL that some developers don't realise. Here's a few things you might not have thought of...

Changing Text Columns en Mass

Example. You have a column that contains file names so that an application can find them on the disk. You want to move the files to a different drive and path, and that would mean updating 1000's of rows to set the new one. You can use SQL to do this nicely much of the time.

update projects set file_output_folder = replace(file_output_folder,'D:\\Data','C:\\DDrive\\Data');

Generating DOS/Linux Batch Files using SQL

Say you need to now create the folders on the disk, cause they don't exist yet. You can use the SQL to generate a DOS batch file like this...

select distinct
concat(
replace(
file_output_folder,
'D:\\Data','mkdir "C:\\DDrive\\Data'
),
'"'
)
from projects;


Sample of Output

mkdir "C:\DDrive\Data\Database\Indexer Output\Blah\XmlToUpload"
mkdir "C:\DDrive\Data\Database\Indexer Output\XML for Transfer"
mkdir "C:\DDrive\Data\Database\Indexer Output\XML for DB Import"
mkdir "C:\DDrive\Data\Database\Indexer Output\test"

Using SQL to generate files like this can save you lots of time!

Using SQL to create more SQL

Example: Someone has written 100 stored procedures that bulk load some data from tables in another database. Rather than painfully triggering them one-by-one, you want to write a new stored procedure that runs them all at once.

You can use an SQL statement to generate another one that you can run. This kind of trick can save you lots of typing!

Some SQL like this will do it...

/* Assumes that the 100 sprocs someone made all start with spLoadTable */
select 'create procedure spLoadAllData as'
union
select concat(concat('exec ', routine_name),';')
from information_schema.routines
where routine_name like 'spLoadTable%'


The output might be something like this:

create procedure spLoadAllData as
exec spLoadTableCustomers;
exec spLoadTableOrders;
exec spLoadTableLineItems;
...96 more!

You can then copy and paste into a new SQL window, tweak it as you see fit, and then run it. You don't really need the union statement at the top, but it does demonstrate how you can add lines to a query.

Tuesday, July 18, 2006

Amazon Queue Service

Amazons Message Queue Service looks very interesting? I'm not that clued up on all this stuff, but there's definately a trend appearing - we can already rent processing power through hosted grid computing networks, so why not rent the computing power to handle messaging?

In case you've not come across the concept of message queues, they're basically a tool to assist distributed computing. This is an area that is interesting me and more these days. I've been working on projects recently where two or three machines aren't really enough, and the prospect of being able to simply add more commodity machines to do more work is an extremely attractive one. Message queues are one technology that can play a big part in this kind of system since they allow separate programs running on separate machines to collaborate without worrying about all the communications overheads (working out which node should receive the message, waiting for responses, detecting ports being blocked, etc). The queue abstracts all that stuff, and more.

You can take your pick of vendor provided message queue implementations (MSMQ, OSMQ etc), but it's really interesting to see someone like Amazon offering a service to do this out of the box, no hardware puchases required.

Amazon's implementation looks nice and simple - just four methods! I guess there will be limits to the application of this service though. Firstly, using machines on an external network could present complications with both security and performance. Is HTTPS available? Would this slow things down even more? Sending messages over the web will be slower than to local networks, so I guess this technology is suited to problems that involve several disconnected networks. The 256K per-message limit might rule out some kinds of application also, such as web spiders and multimedia applications.

Still, and good to see Amazon do something cool with all that infrastructure!

Monday, June 19, 2006

Scary Gross Tree

A Swedish freind of mine, Maria, said that this tree was perhaps the grossest thing she's ever seen. She saw it whilst walking in Nässjö, Sweden.

Basically, it's been infested with insects and turned into some kind of lavae plant!

The tree appears rather white I'd say, if you look at the other piccies you can see why! Grimness!

Thursday, April 27, 2006

Adopting the Kensington Expert Mouse

Last week I purchased a Kensignton Expert Mouse (which is actually a trackball). Finding information online about it wasn't easy, so I thought I'd share my thoughts on the accessory and what it's like adapting to a trackball after a lifetime of regular mouse use.

The main reason I purchased this was because I get pains in my mouse hand and wrist, so decided that my regular mouse + wrist rest weren't agreeing with me. I tend to sit at a computer for 8-10 hours a day, and this must be taking it's toll!

(Lol, my friends have found endless amusement speculating about what repetitive activity might actually be causing the pain, ho ho...)

Why Start with the Kensington?
Having Googled various reviews of various trackballs, I decided that this was the starting point for me. Most people who use it alot are dedicated fans, which is always a selling point. I did look at other trackballs, including the cheaper Kensington Orbit Trackball, the Logitech Cordless Trackman, and many others . Eventually I decided that it would be good to start with one which has a sterling reputation and costs the most, thus increasing my chances of getting along well with it. Unfortunatley I couldn't find a model in any local shop to try, so I just had to order it from Amazon.co.uk and hope for the best.

Note that I've heard great things about the Logitech Trackmans also, but I fancied trying a trackball that didn't require the use of thumb for moving the ball. I figured that if I don't get on with the "classic" kind of trackball, I'll try this next.

Using a Trackball after a regular Mouse
Switching to a trackball is a bit of a challenge. For the first few days it felt wierd, and everything I was trying to do took longer. In fact, even figuring out which position and angle to put my hand and fingers was a thrash.

I've had it for just over a week now, and the situation has improved tenfold, although I'd say I'm still not as comfortable with it as I am with a mouse. The good news is that my hand is falling into place nicely, and even using the thumb to left-click, and pinky to right click feels almost natural. This is pleasantly surprising having being used to a mouse for 20 years, and on day 1 of the Kensington I thought I'd never get used to it.

Kensington encourage you to try the mouse both with and without the wrist-rest (see below). I started without, but after 5 days decided I still wasn't comfy enough and still had a slight wrist pain. Also, I was inclined to keep trying loads of positions because everything feels awquard, but seriously, just give it time and your hand will eventually settle in to its new resting place. Now I chose to use the wrist-rest, which instantly felt better after trying without for several days.


Ugly but Comfy
One thing most people say about the mouse is how ugly it looks. My lodger - John "the Bear" Llewellyn entered teh room and delicately shouted "What the fuck is that thing you crazy fool!!!!?"

As you can see from the images, with or without the wrist rest attached, this look like one ugly mo-fo.

The Perks
There's a few things I like about the trackball so far...

Comfort - Not having to move your arm/wrist is fantastically comfortable.

Matless - Also, not needing a mouse mat is good too. You don't have to worry about cleaning anything, or wiping crumbs off your desk. lol.

Window Scrolling - Sometimes it's more convient to use the window scroll bar to scroll down, as opposed to the scroll wheel on a mouse. I find this to be the case when when quickly quickly moving up and down in a large document.

Whilst the Kensington has does have a scroll wheel, I find it easier to also use the window scroll bar. With the Kensington, doing this is much easier than with a mouse. You simply left-click the scroll bar, then flick the ball up and down to move it, thus scrolling the document. It's much easier than dragging a mouse up and down on the desk.

Covering Large Distances - You can physically flick the ball to move the pointer across large distances very quickly.

The Cons

Accuracy - Quickly moving the pointer to a certain location on the screen seems more difficult. This makes selecting text and drag-drop operations a bit tricky. I hope that this will improve with time so the difference is negligible.

Note: More to come soon...



Monday, January 09, 2006

Windows Ruby On Rails IDEs and Text Editors

I was just reading about how the core Rails team love their Macs and the TextMate editor. Since I personally chose M$ Windows as my developmetn platform, so was interested to read about the comments left by other Windows users who have their own favourite editors.

For your pleasure, here's a summary of those Windows editors:

PSPad
Freeware. Positive feedback on this one since it can be set up to look a little like TextMate. Apparently it has a file explorer panel that will show the TortoiseSVN context menus. Light memory footprint, bags of features including file compare, code helper etc.

RubyEclipse
Open Source. SVN integration. Debugger, code completion (albeit a touch buggy) and a test runner. Uses up about 51MB of ram so a touch on the heavy side.

RadRails
Open Source. Promising reports from users. I've used earlier versions and it was very good. A few bugs and the memory footprint (45MB+) caused me to stop using it, but I'll certainly try it again. Features include SVN integration, WeBrick runner, syntax highlighting, code assist etc...

XEmacs
Open Source. Loads of developers love Emacs, although it comes with a steep learning curve. Apparently it does everything under the sun. I do have plans to learn this tool one day...

TextPad
The text editor I use the most. It's great, light weight and has tons of features. If you dig around the site you'll find some ruby syntax files (and hundrends of others)

[Getting tired now!... so sorry it the descriptions start getting naff! Here's some more to check out]

Scite
Open Source. A small and well loved editor!

UltraEdit
Commercial License, but looks good and users always give good reviews.

Feel free to leave your comments or mention any I've missed...

Tuesday, December 20, 2005

DORO Disappointment


Ever ordered by mail and then discovered it doesn't quite look like it does in the the advert?

I recently purchased a DORO 212IPC Skype Certified phone, and had exactly this experience.

Consider the photo on the right. Looks like a stylish, crisp white skype phone.

Unfortunately, this is not the case. The phone is a creamy off-white colour that makes it look like it's been sat in the sun for too long.

Before returning the phone, I wanted to check with DORO to see if it was a manufacturing error. The staff casually replied...

"No no, the DORO 21I2P isn't actually white, but rather a creamy kind of off-white colour".

Great. Thanks for the honest marketing DORO and for a phone that's the colour of yellow snow.

Tuesday, November 22, 2005

Aarrrggghhh: "The file could not be loaded into the Web Forms designer. Please correct the following error and then try loading it again"

Darn. Darn. Darn. This error has almost cost me a whole day!

If anyone gets this in VS.NET 2003 (I'm doing a VB.NET web project), then here's some solutions:

Workaround #1
Are you using page inheritance? If so, make sure none of your pages declare AND initialise attributes on the same line. So DO NOT do this:

private _securityGateway as Gateway = GatewayFactory.Create()

Instead do this:

private _securityGateway as Gateway

public sub Page_Load(...)
_securityGateway = GatewayFactory.Create()
end sub

This fixed my problems, but I'd already spent all day trying other things :-( Those were...

Workaround #2
Try removing (not deleting) the file from your Visual Studio Solution, and then re-add it back in.

Workaround #3
Delete all files from your Visual Studio web cache. E.g:

C:\Documents and Settings\Tobin Harris\VSWebCache\TOBINSLAPTOP\SomeProject

Workaround #4
Close Visual Studio and then delete as many files as possible from your temp folder. Eg:

C:\Documents and Settings\Tobin Harris\Local Settings\Temp

Anyway, hope that saves someone a day or hair pulling! Can't believe I got so stuck on this, I've never encountered such problems with C# web solutions. Ho hum...