Tuesday, May 29, 2007

CAB error: A circular control reference has been made. A control cannot be owned by or parented to itself.

I've stumbled upon an interesting issue that nicely illustrates how the Composite UI Application Block requires you to change the way you think. It would seem a logical procedure to create your SmartPart control first (call WorkItem.Items.AddNew to do it) then add it to a workspace. But what if your control contains an embedded workspace by the same name? You'll get a circular reference exception ("A circular control reference has been made. A control cannot be owned by or parented to itself.") This is because CAB completely ignores the control hierarchy and has its own system of tracking components. When you add a SmartPart control to the WorkItem, all of its child SmartParts also get registered with the WorkItem, regardless of the fact that your SmartPart hasn't been added to the container control. So when you look for a workspace in the WorkItem, CAB will also detect workspaces inside the SmartPart.

Yeah, but what happens if you use the dependency injection instead of the AddNew method to create your SmartPart? You'd probably be stuck...

Monday, May 28, 2007

Metadata and misunderstandings

A great number of software development problems arises from the fact that the whole philosophy of current development languages and environments is about programs doing something, but without any effort to explain what they're doing. I will give you an example: if you disable a button in a windows form, do you ever give the user a way to find out why the button is disabled? If you perform some database operation in one or another way, will anybody (except a developer armed with a debugger) know what - and more importantly, why - was done?

The answer to my questions would probably be: yeah, so how would you expect me to do it? Log everything? Show message boxes (not exactly useful for disabled buttons) or tooltips? There isn't a standard way to do this and the user would never expect nor find the information. We lack a user- as well as developer- friendly mehanism. If I could write a piece of code like -

btnDelete.Enabled = false -> explain "You don't have enough permission to delete this record";

... the user could possibly be able to see somewhere the list of available explanations (marked with, say, glyphs visible under certain conditions) and review what interests him at that moment. Of course, there's another problem with what I've written here - the framework should somehow be intelligent enough to understand that the explanation should be attached to btnDelete. Or we would have to tell it - in which case we get the following code:

btnDelete.Enabled = false;
btnDelete.StateExplanation = "You don't have permission for this.";

This explanation mechanism is now nothing more than a more intelligent and somewhat differently standardized tooltip. Of course, if the button was completely hidden, we'd display its state somewhere else (for example after a click on some kind of a "what's going on" button).

How about explaining to user the performed operation? We'd need to have a standardized way of buffering explanations and then possibly displaying them as a glyph on a message box that says "The operation was successfully performed. Click here to see what it did and why".

So, in this case it's a relatively simple matter and all that is lacking is a standardized infrastructure. But it would make the application's logic and inner workings much clearer to the user and rapidly drive the learning curve down.

Yeah, but this is not enough, is it? The explanation data cannot be examined by another program, for example. There's no metadata in string explanations. We cannot determine programmatically what the application has done or what it's currently doing, or why has it done something. Why would we need this, you ask? Well, if an application opens a confirmation message box while you are shutting down Microsoft Windows, Windows will say that the application is not responding and ask you if you want to kill it. If the windows could find out what the application is currently doing, it would (or at least could) behave much more intelligently. The "I'm busy, come back later" or "I'm waiting for the user" metadata explanations could be a standard way for the applications to communicate and could probably be built at a higher level into various interprocess communication mechanisms or remote procedure calls. So you wouldn't have to have an "out errorMessage" parameter in each one of your web service methods.

Ok, so does this mean we'd have to write metadata to explain every single method the application can perform? The answer is of course - god forbid, because our development speed would suffer greatly. Not to mention the security issues. But we could start somewhere, try attaching metadata to a minimal set of standard procedures and go from there. Today we are witnessing the convergence of metadata and procedural programming: there are more and more tools that can generate an application from a rich model or execute code based on metadata (.Net attributes), and the programming languages have increasingly richer metadata content. Soon enough the applications will start talking to each other, and at that point C# could be replaced (or more probably extended) with some kind of a metadata language. Look at dependency injection frameworks: the components are already learning how to talk to each other :).