Introducing Microsoft .NET (Pro-Developer)
|
A bonus on the coal I save? Ou ay, the Scots are close, But when I grudge the strength Ye gave I’ll grudge their food to ‘those.’ (There’s bricks that I might recommend—an’ clink the fire-bars cruel. No! Welsh—Wangarti [coal] at the worst—an’ damn all patent fuel!)
—Rudyard Kipling, writing on the false economy of failing to supply enough RAM in a programmer’s machine, “McAndrew’s Hymn,” 1894.
Problem Background
We’ve spent a great deal of time in this book looking at the situation in which Object A creates Object B and calls methods or accesses properties on it. For example, we’ve seen how a form can create a button and set properties for its text and colors. So far we haven’t examined the reverse situation, where Object B makes calls back to its creator, Object A, to notify it that something interesting has happened, for example, the button notifying the form when the user clicks on it. We’ve used events and callbacks and seen them work, but we haven’t looked at the mechanism that .NET provides to make callbacks happen. Now it’s time to dive in.
We need to handle the situation of an object making a call back to its creator.
The need for callbacks is not new, and Windows has implemented them through many different architectures over the years. For example, original Windows controls such as buttons were child windows of their containers, the dialog box or form on which they appeared. They notified their containers of events such as clicks by sending Windows messages to them. This approach made it difficult to pass parameters of more than a few bytes, and it worked only if the objects were actual windows, not just any object. Still, this callback implementation was useful, and in fact many objects that weren’t windows would create windows simply to be able to receive these notifications. Some Windows API functions, such as those for asynchronous file reading and writing, required the caller to pass as a parameter the address of a callback function that would be used to notify the caller of process completion. This approach worked pretty well for code written in C, but it didn’t work well in C++ because C++ couldn’t call a method on an individual object, and, naturally, Visual Basic programmers couldn’t use this approach at all. COM components used COM interfaces to provide callbacks, but again, differences in implementations between various development platforms led to far more expensive testing and special casing than COM’s architects ever envisioned. You never quite knew when you had it right, especially across multiple languages, which was ostensibly the whole point of COM. Enough! We need a generic, standardized way for one object to make calls back to another.
We need our callback mechanism to be standardized across all languages and implementations.
Because no standard for implementation of callbacks existed, it should come as no surprise that no standard for design-time or run-time discovery of callback capabilities existed either. Windows controls provided no information whatsoever, and Win32 API functions contained just a little information in their header files. You had to program these things with a paper manual in one hand. COM objects provided this information in type libraries, with all their drawbacks—they were often absent and rarely standardized. As our .NET components contain standard metadata describing themselves to interested parties, so must our .NET callback mechanism support self-description to clients and development environments.
We need our callback mechanism to contain metadata for the use of intelligent development and runtime environments.
The .NET Framework is an entirely new programming environment. While many of its concepts (inheritance, garbage collection, exception handling) are not new, the extension of these concepts to all applications through commonality of implementation is. We need our callback mechanism to fit into this framework. For example, we need it to be able to call methods of individual objects instead of being limited to raw functions, as the Win32 file I/O functions are. We need it to be built into the framework as a full- fledged member, not just bolted onto the side as an afterthought, as COM connection points are.
We need our callback mechanism to fit into the .NET runtime environment.
|