About this blog
Random thoughts on C#, Windows NT, VoIP, and whatever else crosses my mind
Entries in this blog
Step 2: Use System.Data.OleDb and watch all hell break loose.
Definitely one of the weirdest bugs I've seen.
A bit of background
In our apps, all of the different components are divided into groups such as 'Shutters' and 'Services'. Services are the bits of code that sit in the background and listen to telephony events, or manage database connections, or keep track of contact lists, and so on. Shutters are the GUI components. Shutters tend to rely on services to figure out exactly what needs to be displayed. For example, the contact shutter asks the contact service for a list of contacts to display. Each of these components consists of a primary class, plus various helper classes as necessary.
Because shutters depend on services, it makes sense to initialize the services before initializing the shutters.
We want our application startup code (known as the 'boot manager') to be as generic and reusable as possible - it shouldn't have to know about the details of each particular shutter or service, and of course the lists of necessary shutters and services shouldn't be hard coded. So the question is, how can we ensure that the services are started before the shutters are initialized, while maintaining genericity? Wouldn't it be nice if, say, we could pass an assembly to the boot manager, and have it automatically initialize any services and shutters inside the assembly? How can we pull this off?
Attributes to the rescue!
As mentioned above, each component consists of a primary class. These primary classes contain the initialization code that needs to run when the application starts up. So let's take each one of these primary classes and tag it with an attribute indicating that it is a service or a shutter. We'll call this attribute 'Bootable'.
public class MyImportantService
public class MySuperImportantShutter
On startup, assemblies get passed in to the boot manager, which examines the assemblies for any classes with these attributes. It groups them into services and shutters, and initializes them one after another.
Problem solved! We can now be sure that services are initialized first. But this leads to another problem - dependencies between services. It is quite conceivable that one service might depend on another; the contacts service mentioned above might use the database service to talk to the DB where the contacts are stored. We need a way of ensuring that the database service is initialized before the contacts service. At this point we have to make the assumption that the programmer writing a service knows what other services it depends on. Given this, all that is needed is a 'Prerequisite' attribute that indicates which other services need to be running before the service in question can start.
public class MyImportantService
public class MyOtherService
public class GDNetJournalService
After the boot manager builds the lists of services and shutters, it then orders them based on prerequisites, and starts them as above. (If our intrepid programmer decides to code in a circular dependency, he will be greeted with an exception on startup)
So there you have it - a way of using attributes to ease the pain of initializing your application.
In my never-ending search for a decent Java IDE, I recently decided to install Borland's JBuilder 2005 Foundation. What a mistake that turned out to be. I simply can't comprehend how such shoddy products can actually be released. The forms designer is so slow and buggy as to be beyond useless. The entire IDE is a train wreck of miserable performance, astronomical memrory usage, and sheer ugliness.
I guess it's back to Eclipse for now.
D'oh! This one was caused by some weird interactions between our keyboard shortcut handler and our new localization code. Apparently some strings that weren't supposed to be localized were, which broke some of our accelerator actions. But hey, it's early in the product development cycle. Things are allowed to break.
(And no, this bug wasn't my fault!)
I recently looked at writing some code to integrate with ACT! 2005. ACT! is a personal information management application along the same lines as MS Outlook or Lotus Notes. When I installed the demo and found that it was a .NET application, I was intrigued. When I found that there was an SDK available, I was even more intrigued. Did I finally find an application that makes integration simple and relatively painless? (None of Outlook, Notes, GoldMine or previous versions of ACT! fall into this category).
My hopes were crushed when I actually looked at the contents of the SDK. Some 20-odd megs of assemblies, a few samples, and some incredibly pathetic documentation. The documentation consists primarily of short snippets demonstrating how to perform very specific tasks. Nowhere is there any indication of what any of the assemblies actually do. A high-level design overview or detailed description of the class heirarchy? Nah. We obviously don't need those. Browsing the ACT! discussion groups shows that I'm not alone in my disdain for the SDK.
The moral of the story: If you want your app to be extensible, don't underestimate the value of good documentation. All the functionality in the world isn't worth much if nobody can figure out how to use it.
Incidentally, ACT! 2005 is also one of the slowest applications I've ever used. And I use the term 'used' loosely; it's barely tolerable on my P4 2.8 Ghz dev machine.
In other news, Outlook 2003 uses some undocumented MAPI properties for new contact fields such as 'IM Address'. Thank goodness for OutlookSpy, and no thanks to MS for once again making it unnecessarily difficult to write code that integrates with Outlook.
ReactOS 0.2.4 was released a few days ago. Download it here, or have a peek at the changelog here.
-Projects I'm working on at school
-Interesting technial issues I come across at work (I write .NET-based software for corporate VoIP phone systems)
-Various graphics & systems programming projects that I am working on
That's all I have to say for now ... the real point of this post is just to test out the journal system.