Category Archives: Software Architecture

No one’s competent

2
Filed under Software Architecture, VB Feng Shui

There’s an interesting opinion piece by Kathleen Dollard in last month’s Visual Studio magazine. The latest issue has another piece by Kathleen that is very similar. There’s no link to the latest one, because that issue has just come out (I got mine not 30 minutes ago).

In them, she’s essentially saying that the .NET framework, and all the various supporting enterprise frameworks, have become so large that no one can hope to be competent enough in them to be able to intelligently determine what to use, when to use it and when to stay away.

I couldn’t agree more. But despite comments in the article that she is “more optimistic today” and that “the revolution has begun”, I still come away from the articles sensing a muted dread. Fear that suddenly, skills you possess today and have honed over the years will become worthless. The value of the knowledge you currently have is drying up like last weeks doughnut holes.

And I’m just not down with that.

The fact is, my experiences seem to suggest that the less you know about these high level frameworks, the better off you are. I’m not saying don’t get familiar with them. I’m saying that if you spend time to learn the basics of computer functionality, hardware, interfaces, binary, and object oriented principles like encapsulation, polymorphism and inheritance, details of specific frameworks just tend to come out in the wash.

On the other hand, if you spend all your time focusing on a specific framework, when it’s no longer de rigeur, you’re screwed.

Microsoft has created some great stuff, to be sure, and some of the newest bits out of the pipe certainly seem compelling, WPF probably more so than anything else. But it’s also thrown out plenty of red herrings, costing companies untold money before people realized that “the silver bullet of the day” probably wasn’t a good idea after all.

Back to the knowledge issue though. When VB1 came out, and only a bit later VB3, everyone exclamed at how great it was because “you didn’t have to know the nuts and bolts of the Windows API to get something built for Windows”. Which was true, unless you wanted to build an program you could actually do something with.

The fact is, VB was like that first step down into the pool. It lets you get your feet wet and get used to cold water before you dive in headfirst. Plus you get to feel for sure whether there’s any water in the pool.

But eventually, you either dive in, or you decide you don’t like programming.

VB.Net has always been more like the diving board. You either walk away, or you dive in, and you won’t know if there’s water in the pool till you feel it or you bash your skull on the gunite.

I think there’s a bigger issue here, though. Emphasizing all these layers of Linq, Sharepoint, WPF, WF, WCF, Ajax, and blah blah blah, won’t help encourage anyone to dive in, and that’s what VB.net needs to be doing. Instead we get, what, the MY classes. Puh..leaze! At least edit and continue finally came back with VS 2005. Where’s the genius that decided it’d be a good idea to leave it out in the first VS releases, anyway?

Don’t get me wrong. You can create some hardcore stuff with VB.Net, a lot easier than was ever possible in VB. But you get some hardcore baggage coming along for the ride too. And that’s unfortunate, because falling CS enrollments may mean a pretty sweet employment future for me, but it bodes some not so sweet prospects for our long term technological advancement as a nation.

And dammit, I want my flying car before I GOTO END !

Monolithic, Client-Server, 3-Tier, n-Tier

0
Filed under Software Architecture, VB Feng Shui

You are writing all your applications with a Client-Server architecture, right?

Oh, wait, this isn’t the late 90’s.

You are writing all your applications as 3-Tier assemblies, right?

Oh, wait, this isn’t the early 2000’s.

You are writing all your applications… Oh, to heck with it.

What’s the architecture du jour these days, anyway, n-tier? x-tier? SOA? XYZ-PDQ?

So what’s all the hubbub?

I propose something radical. Logically tier your code based on functionality, not locality. If you do that properly, monolithic, Client-Server, 3-tier, n-tier, x-tier, tears for fears, it won’t matter.

Why not?

Because if the code is properly organized and logically tiered, you’ll be able to easily move it wherever it needs to go to create (and remove) whatever tiers become necessary.

For example, I once worked for a company building a sizable billing package based on SQL Server. We wanted it 3 tier (Presentation, Business Logic, and Data Access), but we also needed it to be:

  1. easy to debug and maintain, and I mean easy, not the “learn how to jump through hoops faster” easy, but really easy. The dev team was small. This was a requirement.
  2. easy to deploy in a demonstration mode. If a prospect couldn’t fire up a CD install and in 5 minutes or less be playing with it, it wasn’t going to fly.
  3. capable of scale-out deployment to accommodate multiple report generation servers, data analysis servers, etc.

In the end, we designed a server app as the BLL (it actually ran as a service), a database chock full of highly optimized stored procs as the DAL, and a fat client that contained not only the user-facing interface but also the entire server app internally. And the key to all this was that the code for the server was exactly the same code as was in the client. The code was literally shared between projects in our VCS.

When connected to an actual server component, it got all the benefits thereof. But for debugging, it was unbelievably efficient to have both the client and server right there running at one time not only in the same IDE, but actually as part of the same executable. And deployment was a snap because the demo install didn’t have to bother with a server installation, it just created the DB and dropped the client on the machine.

If we’d needed to split functionality out farther, it would have been a very straightforward process because internally, everything was already split out.

The bottom line is:

Get the logical tiers right and encapsulate with a vengence.

Note to self: Vengeful Encapsulation. Sweet band name!

Error Handling Strategies

0
Filed under Software Architecture, VB Feng Shui

I once wrote an article about error handling in VB6 for Visual Basic Programmer’s Journal (Sept 2001, jeez that seems like a long time ago! {edit} and it would appear that that link is long since dead 🙁 ). It was born out of the need for a comprehensive framework for handling errors in an app I was working on at the time.

Since then, I’ve expanded the framework several times and it’s grown into something quite handy. Once I get it cleaned up a bit for public consumption, I’ll make the new and improved version available.

I’ve since been looking at the .NET error handler framework, and while it’s certainly much improved over the VB6 days, it still leaves a lot to be desired.

At the very core of handling errors is the division of error types into two distinct classes:

  • Expected Errors
  • Unexpected Errors

In a perfect world, every possible error is an Expected Error and there are no errors that can occur within your program that the code isn’t written to intelligently deal with.

At the other end of the spectrum, is, of course, where most textbook and magazine article sample code lies; where every error is an Unexpected Error that will crash the program.

Unfortunately, real world limitations on time, money, manpower, etc tend to force all code somewhere south of Nirvana.

The .NET fanclub used to decry VB’s on error goto as antiquated technology, and trumpeted try catch as the silver bullet of the day. And I suppose:

On Error Goto Catch
Try:
...code to try...
Goto EndTry
Catch:
...code to handle any error in the try block...
EndTry:

is quite different from

Try
...code to try... 
Catch ex as exception 
...code to handle any error in the try block... 
End Try

as long as you’re only looking at their checksums<g>.

Sure .NET incorporates a wealth of metadata about the exception. The module, function, line number, etc are all available directly while handling the error. But something’s missing.

Oh, yeah, What about those Unexpected Errors?

.NET does have the Exception Handling Application Block and it looks very promising, although it also looks very involved. And do you really want to be able to configure exception handling policies via config files? I mean, beyond indicating the level of logging you want (verbose, medium, low, off), and the email address to send exception report to (unluckysupporttech@mycompany.com), I’m having a hard time coming up with anything else I’ve ever needed to dynamically configure in my apps for exception handling. But, I won’t say it couldn’t be useful.

In the end, I suppose the thing that bothers me most about the EHAB, and the whole structured exception movement in general, is that it really does nothing to address the Unexpected Errors in an application. You still have to wrap your entire procedure in a TRY block in order to be sure that you catch any exception raised in that procedure. Otherwise, the exception is simply propagated up the call stack to the first point that is covered by an exception handler. The good news about .NET, though, is that at least, in those cases, you can still retrieve a call stack back to the real source of the exception and log it. With VB6, no such luck without some sort of framework.

My other issue is that Try Catch style exception handling forces the declaration of how you intend on handling errors to the END of the function you’re looking at. In this age of declarative programming and metadata-attributed interfaces, that just seems so…yesterday.

Take my above comparison of try catch and on error. What actually happens to the error is stated down at the end of the procedure in both styles. Now. I can understand that approach if you have code dedicated to handling specific errors, but then, those are Expected Errors. For the Unexpected Errors, I’d rather know, declared right up front, how the prodecure intends to handle them.

That was the impetus of my article way back when:

  • Provide a framework that could provide a call stack that VB6 was lacking
  • Provide a means of clearly declaring how the procedure intends on handling Unexpected Errors.

Compare a typical Try Catch structure:

Public Sub Test()
   Try                                          
   .....Lots and lots and lots of code....
   Catch Ex as Exception
   ....how to handle specific exceptions, plus how to handle general exceptions...
   End Try
End Sub

with a prologue style declaration like I use in my error handling framework for VB6:

Public Sub Test()
'############### ERR HANDLING #############
Dim Err As CErr: Set Err = New CErr: On Error GoTo Problem
Problem:
Select Case Err.Handle(EHF_PRESENT or EHF_ALLOWRETRY, MODULE, "Test")
Case EHE_NONE: Case EHE_RETRY: Resume: Case EHE_PASS: Resume Next: Case EHE_RESET: Resume Problem
End Select
'##########################################
   .....Lots and lots and lots of code....
End Sub

The code states right up front how unexpected errors are handled (in this case, EHF_PRESENT or EHF_ALLOWRETRY indicates that the user will be shown a dialog and allowed to retry the operation). There’s a bit more verbiage here because of the requirements of VB6, but that’s not the point.

Personally, I’d prefer it if every routine in .NET could be (or maybe even had to be) attributed as to how unexpected errors are to be handled. Those that need to show a dialog would do so based on one or more “predefined” dialogs that depended on where in the app the error was thrown.

And for those apps that you never want to show an error dialog, you could instead indicated that any unexpected errors should be logged to the Event Log (or somewhere else) and then press on as best as possible.

Unlike the implications in so many magazine articles, error handling is hard. Proper error handling is like a prostate exam; you know you have to do it, but you’d really rather not bother.

InstallShield Upgrade Joyosity

7
Filed under Installations, Software Architecture

I’ve been hunting down an issue with an InstallShield Installation for almost a week now.

Very strange. I have a new installation that is a BASIC MSI install (meaning it contains no funky InstallScript at all, and is this fully MSI compliant).

It is intended to upgrade several previous installations, one of which is also a BASIC MSI, but the others are all InstallScript MSIs.

When I first started testing the upgrade process, I did the install of the old version, followed by an install of the new version. When I went to ADD REMOVE PROGRAMS, the new was there, but the old version was as well. The upgrade didn’t work.

Grrr.

So I start digging. Eventually, I determined that the old version was actually being uninstalled (I paused the install midstream and sure enough, all the old files are one point are completely removed). However, for some reason, the entry in the Add Remove Programs list was not being removed.

More digging.

So I reset my test, installed the old version and at Macrovision’s request, I searched the reg and found a key here:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F1C8EEFE-8019-44AB-8AA9-D6F13E3BFAF0}]

that contained all the info about the old installation.

There’s a value called NOREMOVE set to 1. Hmm, that sounds suspicious. So I set it to 0 and install my new version.

No joy, the old version is still listed in ARP. However, when I went back to the registry to check that key, it was gone! What the hell!? Ok, the entry in ARP must be coming from somewhere else. A few reg searches later turned up this key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\InstallShield_{F1C8EEFE-8019-44AB-8AA9-D6F13E3BFAF0}]

Notice that the GUID there is the same as the other GUID, but this one has “InstallShield_” at the front of the key name.

Delete THAT key, and suddenly, the ARP entry is completely gone.

It would appear that upgrading an InstallScript based install with a BASIC MSI install unintentionally leaves behind a key that it shouldn’t. Some searching the KBs with more specific keywords turned up exactly that.

An InstallScript based install created two entries in the Uninstall registry key, but one is ‘hidden’ from the ARP list view.

A Basic MSI install only creates one key. And if you upgrade an InstallScript based installation with a Basic MSI installation, that second key (the visible one) won’t get removed properly.

You have to add an entry to the RemoveRegistry table in the MSI file and connect it to a component that will be installed by your new installation.

Didn’t table-driven programming constructs die back in ’91 with Magic. No, wait. Ack, they’re still alive?!

Well, tried it then and hated it, still hate it today. To each his own.

SQL and Portability

0
Filed under Software Architecture, SQL

There’s an interesting discussion going on at SQL Server Central about applications and database portability.

The question thrown out was “How valuable is portability to your application”.

And by portability, they’re referring to portability across different database backends. Can your app run on Oracle, SQL Server, MySQL, etc, or do you just lock down to a specific vendor, and sell to your apps strengths and not DB portability?

It’s an interesting question and from the responses so far, it would seem that DB portability is a 4 letter word. But I think many of the responses are a little short sighted or limited to the DBA/developer perspective.

There is one comment saying something along the lines that an app this company purchased was DB agnostic and was found to contain no where clauses. Now that may have been an exageration to make a point, but I’d argue that an app like that was poorly architected from the outset. The fact that it performs poorly would seem to have less to do with being DB agnostic and more to do with just poor coding/architecture. My guess is, if you looked past the DB code in that app, you’d find a lot more to dislike as well.

The bottom line in any business is 1) The customer is always right and 2) you have to sell the product you have in order to make the product you want to sell.

Now, as to part 1, I’m not saying you can’t educate the customer, but in the end, if they really want Oracle as their backend, there may be some business reasons for that that you can’t sell around. And if the IT shop of that customer is centered on Oracle, good luck going in with a SQL Server based app.

I suppose it’d be nice if every shop was an IBM sized house that could hire DBAs specifically to design and support the backends for every reasonable DB, but most shops don’t have those kinds of resources.

In small shops, it’s all about leveraging code as much as possible.

VB and Lotus Notes

2
Filed under EMail, Software Architecture

Not something that often ends up on a VB developer’s plate I suspect, but I had need to do some investigating of Lotus Notes and possible integration/extension development using VB (classic, v6.0, not .NET).

Come to find out, Notes does have COM support as of 5.0.2b, so appearently, you do not have to dive down into ever joyous C++ in order to take a stroll through Notes-ville. Unfortunately, finding actual documentation for that object model online feels like finding your kid’s matchbox car that fell out of their pocket in the ball pit at Chuck E Cheese. I’ll try to post my results, if any, when I have some.

Now, as to why you’d want to dig into Note, one look here should dissuade all but the foolhardiest of souls. Granted, I know very little of the internals of Notes. From what I understand, internally, it’s actually a quite capable system, and has been for years and years. Still, those screenshots speak volumes.

Me? Well, I have a foot and here’s a Smith and Wesson. With any luck, the obvious won’t happen next.

Application Configuration

0
Filed under Software Architecture, VB Feng Shui

I’ve played a bit now with the .NET configuration model and while I can certainly see some elements in there to like, it seems to me that it falls short in a number of different ways.

First off, it doesn’t really have any concept of “multi-level configuration.” In fact, it’s basically a single level XML file (granted, you could create a hierarchical organization within that single xml file, but there’s other issues with that). .NET does help a bit with the concept of a machine config file, but from what I can tell that’s about as far as it goes.

Second, the default behavior is to locate the application config file in the same path as the application itself. That’s great if your user is running as administrator, but not so great in more locked-down situations where users do not have full admin rights. In those cases, configuration that’s writable needs to be stored somewhere within the user’s profile directory structure. This is just going to get worse with Vista, too.

Ok, sounds good but what, you may be asking, is a multi-level configuration scheme, and why would I want one? Almost every app I’ve ever worked on, short of the trivial utilities I’ve built, has required this sort of configuration scheme (or at the very least greatly benefited from having it). It almost always follows along this line:

  • Administrator specified User specific configuration (rarely used, the user cannot change this configuration)
  • User specific configuration (that the user can change dynamically)
  • Group specific configuration (typically set by a system administrator or group admin and read only to users)
  • Machine specific configuration (typically set by a system admin, and rarely used, read only to users)
  • Application global configuration (typically set by the system admin, read only to users)
  • OEM defaults (typically set by the app developers to provide default config values, generally readonly by everyone except the developers)

At each level, the system provides for an essentially unlimited number of name value pairs that can be cordoned off into groups (or sections as they used to be called in INI files). Some may argue that a section-name-value system like this is too limiting and you should always accomodate full hierarchical structures, but I’ve found the extra functionality rarely necessary.

Of course, the type of value (string, int, date, etc) for a particular setting is defined within the application, but value types might also be defined as OEM default settings. Should sysadmins really be able to change setting X from a string to a date? I’d imagine not usually.

The trick and the real beauty of the system is in the way that setting values are resolved. The resolution logic basically says that if the app can find a setting at a higher level in the hierarchy, it uses that value. Otherwise it searches down the hierarchy till it either finds a value, or till it drops to the OEM defaults. If no setting is specified at the OEM level, the system defaults to blanks, or 0’s depending on the data type.

So, for instance, the code might ask for the setting “AskOnExit” from the “Prompts” section. The config handler needs to look first at the “level of most significance” which, in the above list of levels, would be the Administrator specified user specific settings (ie those settings that are set on a per user basis, but that the user himself doesn’t have the authority to change.

If the setting isn’t found there, the code continues down the hierarchy, looking at each level in turn until eventually in run through them all and returns the default or a blank or 0.

And, of course, you also have to provide a means to retrieving and writing a setting at a specific level in the hierarchy, for those settings that are always application level or machine level or what not.

Obviously, such a scheme requires a little more work up front, but the configuration flexibility (especially when you’re talking about major, multi user systems with lots of configuration options, typically off-the-shelf, reseller-friendly applications like accounting systems or CRM packages), is a huge selling point to admins and users alike.

Why, then does configuration handling in .NET seem so archaically primitive?

Could you roll all these levels into that singular .config file? Sure, when where would you put it? In the Application path? No, users won’t typically have write rights there. Under the user’s Application Data folder in the Profile? No, can’t put app wide settings somewhere that only a single user can access it. How about that machine config file. Again, not writable by typical users.

It’s funny that Windows already has a rights system that is very stable, quite flexible and easy to work with, both manually and from within code and yet it often goes completely unused by larger apps. I’m talking, of course, of the file system.

These days, though, web apps are de rigueur and you can’t go assigning file system rights to web users. There’s no way that would fly with most web developers (you weren’t really thinking of something like that, right?). So, roll it up into a simple table, with a getSetting and a setSetting stored procedure to simplify the coding. With proper indexing, and a little intelligent caching, it’ll be every big as fast as using the .NET configuration functions, and whole lot more flexible.

Long story short. If your sideline utility needs to save a few settings, use the .NET configuration. It’s fast, relatively easy and convenient. But for just about everything else, take a little time and do it right.

Your users and their sysadmins will thank you.