If we are VB developers and the goal of VB is to hide the COM+ architecture, why do we need to know things at a low level? Well, it turns out that VB is good about hiding 90% of the technology. The problem is that the other 10% makes life very difficult. A number of topics can be mastered only if you understand how the architecture works internally. It becomes a lot easier to solve those problems if you have a good grasp of the architecture than if you don’t; in fact, in some cases, it becomes possible for you to solve those problems, whereas it remains impossible without some knowledge of the internals.
It would be easy for me to just tell you to stay away from this or that feature or to turn on this option in x situation and to turn it off in y situation (and in fact a lot of authors do just that). I felt that, as a VB developer, I’d had enough of not knowing why some things work the way they do; life gets a lot easier when you know exactly what’s happening. It turns out that with some knowledge of the internals, you can also stretch VB farther than you could imagine. Let’s take a look at some of the topics in the troublesome 10% of COM/COM+ technology.
One of the most frustrating things in Visual Basic is versioning. The problem with versioning is that VB tries to hide too much from you. You may have had, for example, the situation in which you recompile your ActiveX DLL or ActiveX EXE and then find that the client program using it stops working. Some developers end up rebuilding every component and every client every time a little change is made. However, it turns out that one of the reasons VB uses COM as its core technology is to prevent the situation in which you have to distribute everything again to the client.
The problem is that VB components use COM interfaces to group their methods, and these interfaces have a globally unique identifier (GUID) number assigned to them. The client uses GUIDs to tell COM what interface and what component it wants to create. C++ developers have full control of how the GUIDs are generated and when they are changed—they work with GUIDs directly. VB developers do not look at GUIDs directly; the compiler and debugger generate the numbers automatically as needed. By default, the compiler assigns a new GUID each time you compile the project. When you compile the client using that interface, the client code becomes dependent on the GUID for that interface. Since the default in VB is to generate new ones, each time you re-compile the component’s project, you end up with a new GUID, and the existing clients stop working.
If you are an experienced VB developer, you may be thinking, “That’s not a problem—all you have to know is how to set the Version Compatibility options in Project Properties.” It turns out, though, that those settings work well only part of the time. Those options are meant to instruct VB when to keep GUIDs the same as before and when to generate new ones. However, sometimes even a small change to one class is enough to force VB to change the GUIDs for every class in the project.
The versioning problem is easier to master if you
use interface-based programming,
understand the COM activation sequence, understand how GUIDs are
assigned to each part of your component, understand the difference
operator and the
function in VB, and understand the
difference between the versioning options. To make it even easier to
master, however, you could take full control over interface
declarations by creating your own type libraries. A type
library is a binary file that describes the interfaces and
components in an ActiveX DLL or ActiveX EXE. VB automatically creates
a type library and embeds it as part of the ActiveX DLL or ActiveX
EXE. In extreme cases, it turns out that you could even replace the
type library VB creates with one you create.
You can, of course, develop components and COM+ applications without knowing about any of these disparate topics and techniques, but, sooner or later, you’re going to run into versioning problems. And quite possibly, others may suspect that the versioning problems resulted from your breaking the “COM contract.” Armed with knowledge of these topics, you’re much less likely to run into versioning problems. As a result, you’ll be able to create much more sophisticated COM+ applications that at the same time are far more robust and require far less maintenance.
The second aspect of COM programming that seems to surface before long is threading. It’s true that as a VB developer you do not have to create your own threads, or even worry about multiple threads making calls into your methods at the same time. However, knowing about threading can sometimes save you a lot of problems. The first evidence that the VB team could not hide threading issues altogether is in Project Properties, where there is a setting for ActiveX DLLs called Threading Model. How can anyone choose the value for this option without understanding what a threading model is in the first place? To make matters worse, there are settings like Unattended Execution and Retained in Memory that complicate things a little.
The way in which VB manages variables and objects like the App object and the Err object when your objects work in different threads also makes threading knowledge necessary. It turns out that global variables (and we can discuss the merits of using them in the first place in a later discussion) stop being global when your components run in different threads. You have to keep in mind that even though your component code may not be creating multiple threads, COM+ will be creating multiple threads and managing instances of your components, sometimes in different threads and sometimes in the same thread. So data that your application treats as global is suddenly not so global anymore.
Finally, there are a number of services in COM+ that are not available to VB developers solely because of our threading model, and there are some services that were designed to accommodate VB’s threading models. What makes things more difficult is that it is very easy to break the COM safety for VB objects and in some cases cause deadlocks if you do not understand how COM’s threading mechanism works.
The third issue that quickly comes into play is the myth of location transparency. The problem with location transparency is that COM has taught us that components should work equally well when they are on the same thread as when they are in a different process on a different machine. The problem is that round-trips along the network or the Internet take a lot longer than direct calls to a component on the same thread. Thus, this is another area in which knowing what is happening internally, and especially knowing how to adjust settings in COM+ services, can greatly increase your performance.
Some developers make the mistake of putting a component in a COM+ application and leaving the settings with the default values. It turns out that the defaults are there for backward compatibility with MTS. By turning off about five features, you gain lots of performance benefits and consume a lot less memory.
The fourth aspect of programming that requires a low-level knowledge is transactions. Nearly every database application in COM+ eventually deals with the transactions. Many developers make the mistake of turning on transactioning support for their components just because they want to use transactions in their code. In Chapter 9, you will learn everything that happens when you turn on transactioning support in COM+ applications.
Finally, there is the issue of security. VB has absolutely nothing for adjusting security in COM components. This is one of the aspects of the architecture that is just not addressed with high-level features on the Visual Basic side. As a result, it is very difficult for VB developers to readily understand how to ensure that information is transmitted in a secure fashion between the client program and the server program. It is also very difficult to understand how security in Internet Information Server (IIS) affects your COM+ applications.