The Evolution of Microsoft s Multitier Platform

[Previous] [Next]

As I mentioned earlier, Windows 2000 and COM+ offer a platform for building multitier applications. But many of the core technologies that make up this platform have been around for a long time. It's important that you understand how the various pieces of the platform have evolved over the years.

As far back as the early 1990s, influential individuals at Microsoft realized that a disproportionate amount of money was being spent on infrastructure in the development of large multitier systems. They realized that companies wanted to spend more time writing custom business logic and less time writing complex code to address issues such as sharing middle-tier resources and monitoring distributed transactions. Microsoft's entire multitier strategy is based on the assumption that companies would rather have someone else create the generic yet critical pieces of a framework for distributed applications.

As Microsoft's multitier strategy has evolved, its attempts to give it a name and a consistent identity have created some confusion. The marketing folks seem to dream up entirely new names and acronyms every year or two for technologies that have already been around for a while. For example, Microsoft's latest name for its platform is the Windows Distributed interNet Applications Architecture (Windows DNA). From a marketing perspective, Microsoft needs new fresh names to compete with similar technologies such as Corba and Enterprise JavaBeans. From your perspective as a developer, these name changes don't mean much. Try not to let them confuse you. No one's reinventing the wheel here—they're simply starting to call it a Circular Locomotion Device (CLD).

Every topic discussed in this book fits under the vast umbrella of Windows DNA. I won't even attempt to cover all the DNA-related technologies, such as DHTML and client-side scripting. The term DNA encompasses everything that Microsoft has ever done to help companies build multitier applications. Many programmers avoid the term altogether because they don't want to be confused with someone from the marketing department or with a nontechnical manager. If you really want to talk shop in development circles, you have to understand all the important technologies that make up the platform.

The Foundation: COM

Microsoft's multitier strategy is founded on a core technology known as the Component Object Model (COM). While COM offers many benefits, it is a complex technology that involves several challenging concepts and tons of low-level details. Some of these concepts and many of these details are critical to your understanding of how to properly build middle-tier components for a COM+ application. Many other details associated with COM are no longer relevant or are important only to programmers who are building presentation-tier applications. You need not concern yourself with such COM-related topics as object linking and embedding (OLE), ActiveX controls, and connection points (such as Visual Basic events), so I have omitted them from this book. This book focuses exclusively on the details of COM that are important for programmers who are building nonvisual components for the middle tier.

The term COM means many different things to many different people. On the one hand, it's a specification for writing reusable software that runs in component-based systems. On the other hand, it's a sophisticated infrastructure that allows clients and objects to communicate across process and computer boundaries. Many developers who are already COM-savvy see it as a new programming style and a set of disciplines that are required in order to work in a Microsoft-centric environment.

The COM programming model is based on the distribution of class code in binary components. This means that software (components) that adheres to COM can be reused without any dependencies on source code. Developers can ship their work as binary files without revealing their proprietary algorithms. The reuse of code in a binary form also eliminates many compile-time problems that occur when applications are assembled using a development style based on source code reuse.

Before component-based technologies such as COM were available, large applications were built by sending hundreds or even thousands of source files to a compiler in a single batch job to build one executable file. This development style, with its reliance on monolithic applications, requires huge executables and long build times. Also, to take advantage of a modification to a single line of source code, the entire application must be rebuilt. This makes it increasingly difficult to coordinate the programming teams working together on a large application. Maintaining and enhancing a monolithic application is awkward at best.

Component-based development solves many of the problems associated with monolithic applications. It allows development teams to ship binary files rather than source code. Binary components can be updated independently and replaced in the field, which makes it much easier to maintain and extend an application after it's been put into production. Most people agree that using COM or some other component-based technology is an absolute requirement in the development of a large information system.

COM is based on object-oriented programming (OOP). This means that COM is about clients communicating with objects. COM exploits the OOP paradigm to achieve higher levels of reuse and maintainability than is possible with other models of binary reuse. COM clients and COM classes typically live in separate binary files. COM defines an infrastructure that enables clients to create and bind to objects at runtime.

A platform based on object-oriented component reuse must provide a dynamic class-loading mechanism. This is one way in which Java and COM are alike. A client creates objects at runtime by naming a specific class that's been compiled into a separate binary component. A system-supplied agent tracks down the class code, loads it, and creates the object on behalf of the client.

Binary reuse makes it far easier to incorporate small changes to an application. For example, a minor bug fix or a performance modification can be made to a DLL. The DLL can then be recompiled and replaced in the field without adversely affecting any of the client applications that use it. Systems based on source code reuse must typically recompile every line of code in the entire application, which makes maintaining and extending software cumbersome and expensive.

The principles of binary reuse allow you to construct COM-based applications using language-independent components. When several teams are building components for a single system, each team can choose its programming language independently. Today's list of COM-enabled languages includes C++, Visual Basic, Java, Delphi, and even COBOL. Each team can select a language that matches its programming expertise and gives it the best mix of flexibility, performance, and productivity.

For example, if one team requires low-level systems code, it can use C++ for its flexibility. Another team that's writing and extending business logic and data access code for the same application can use Visual Basic for its high levels of productivity. The ability to mix and match languages makes it easier for companies to make the best use of their existing pools of programming talent.

Interface-based programming

Microsoft engineers made many important architectural decisions as they designed COM. But one of the most profound decisions was to require that COM have a formalized separation of interface from implementation. This means that COM is founded on the idea of interface-based programming.

The concept of interface-based programming wasn't a clever new idea from Microsoft engineers. This programming style had already been adopted by academic computer scientists and by organizations that needed to build large, extensible applications. Interface-based programming was pioneered in languages such as C++ and Smalltalk, which have no formal support for the concept of a distinct, stand-alone interface. Today languages and tools such as Java and Visual Basic have built-in support for this style of programming. So while Microsoft doesn't get credit for the idea, it should definitely get credit for seeing the elegance of interface-based programming and using it as the cornerstone of COM.

An interface, like a class, is a distinct data type. It defines a set of public methods without including any implementation. In another sense, an interface defines a very specific protocol for the communication that occurs between a client and an object. The act of decoupling the interface from the class or classes that implement it gives class authors the freedom to do many things that would otherwise be impossible. A developer writing a client application against an interface definition avoids dependencies on class definitions. Chapter 2 introduces core concepts of interface-based programming. While it might be one of the more challenging chapters of this book, its concepts are important to your understanding of how and why COM works the way it does.

Distributed COM

From the beginning, COM was designed to transcend process boundaries. The earlier releases of COM made this possible only when the client process and the server process were running on a single computer. With the release of Microsoft Windows NT 4, support was added to COM that allowed this interprocess communication to extend across computer boundaries. Microsoft created a new wire protocol for COM that made it possible to deploy distributed applications in a LAN environment. This was a significant milestone in Microsoft's strategy for enterprise computing.

At first, Microsoft struggled to come up with a marketing term to signify that COM could finally be used to create objects from across the network. The name Distributed COM (DCOM) won out over Network OLE when Windows NT 4 was first shipped in August 1995. Today neither term is in style among developers. Distributed COM is currently the proper term for talking about COM's wire protocol, although many developers think that COM itself is a distributed technology and that putting Distributed in front of COM is redundant.

As I mentioned earlier, COM's support for distributed applications is based on an interprocess mechanism named Remote Procedure Call (RPC). RPC is an industry standard that has matured on many platforms. Microsoft enhanced RPC with object-oriented extensions to accommodate COM, and the resulting implementation on the Windows platform is known as Object RPC (ORPC).

COM and RPC have a symbiotic relationship. COM offers RPC an object-oriented feel, and RPC offers COM the ability to serve up objects from across the network. In Chapter 3, we'll look at how COM leverages RPC to transparently call methods on remote computers by sending request and response packets between clients and objects and how clients still invoke methods as usual, as if the objects were nearby. It's remarkable how COM's architects were able to hide so many of the details required by RPC from both middle-tier programmers and client-side programmers.

From COM to MTS

The release of Microsoft Transaction Server (MTS) was a significant milestone in the evolution of the platform.MTS is a piece of software created for Windows NT Server. MTS allows business objects running on Windows NT Server to run and control distributed transactions from the middle tier. However, MTS is much more than a transaction monitor; it provided a brand-new runtime environment for COM objects running in the middle tier. MTS added lots of critical infrastructure support that wasn't included with COM. In particular, it added new support for distributed transactions, integrated security, thread pooling, and improved configuration and administration.

The name MTS has caused confusion because the software wasn't created just for companies that want to run distributed transactions. MTS provided a vehicle for Microsoft to ship the next generation of its distributed application framework. Middle-tier objects targeted for Windows NT Server should be run in the MTS environment whether or not they're involved in transactions. People get confused when they learn that MTS can be used to deploy objects that are nontransactional. To eliminate this confusion in Windows 2000, Microsoft has changed the name of the middle-tier runtime environment from MTS to COM+. The transaction support that was created for MTS is also included in COM+. If you already know how to program transactions using MTS, you don't need to learn much more to write transactional components for COM+. Things work almost exactly the same way. (Programming transactions with COM+ is covered in Chapter 8.)

In addition to supporting distributed transactions, MTS extended COM's security model. MTS security is based on the notion of roles. A role is an abstraction that represents a security profile for one or more users in an MTS application. At design time, a developer can set up security checks using roles in either a declarative or a programmatic fashion. At deployment time, an administrator maps a set of roles to user accounts and group accounts inside a Windows NT domain. The role-based security model of MTS provides more flexibility and more granularity than the original security model provided by COM.

Another significant feature that MTS added to the platform was a scheme to manage concurrency by conducting thread pooling behind the scenes. MTS introduced an abstraction called an activity, which represents a logical thread of execution in an MTS application. MTS programmers should write their applications to provide one activity per client application. The MTS runtime automatically binds logical activities to physical threads. Once the number of clients reaches a predefined threshold, the MTS runtime begins sharing individual threads across multiple clients.

Multitier applications that use a thread-pooling scheme scale better than those that use a single-threaded model or a thread-per-client model. A single-threaded model removes any chance of concurrency because it can't execute methods for two or more clients at the same time. A thread-per-client model results in unacceptable resource usage in larger applications because of the ongoing need to create and tear down physical threads. The goal of a thread-pooling scheme such as the one built into MTS is to create an optimized balance between higher levels of concurrency and more efficient resource usage. In this respect, MTS takes on a pretty tough task and neatly tucks it under the covers.

One other significant feature of MTS was improved support for computer configuration and network management. COM made it tricky and expensive to deploy and administer larger COM-based applications in a network environment. The MTS administration tools made it much easier to configure and manage the server computers that run middle-tier objects. Unlike COM, MTS makes it possible to manage many server computers from a single desktop. MTS also provides the tools to generate client-side and server-side setup programs.

Attribute-based programming and interception

MTS introduced a significant concept to the platform's programming model: attribute-based programming. Services provided by the platform are exposed through declarative attributes. Attribute settings are determined by programmers at design time and can be reconfigured by administrators after an application has been put into production. Attribute-based programming is very different from the way that most operating systems have exposed system services in the past.

Traditionally, operating systems have exposed services through a set of functions in a call-level application programming interface (API). In this model, an application leverages system services by making explicit calls to the API. This means that you must compile explicit system-level calls into your application. If you want to change the way you use a system service after an application is already in production, you must modify your code and recompile the application. A programming model based on declarative attributes is much more flexible.

Let's look at an example to give you a clearer picture of how declarative attributes work. A component in an MTS application has an attribute that tells the MTS runtime environment whether it supports transactions. If a programmer marks a component to require a transaction, objects instantiated from the component are created inside the context of a logical MTS transaction. When a client calls one of these transactional objects, the MTS runtime automatically makes a call to start a physical transaction. It also makes the appropriate call to either commit or roll back the transaction. The point is that programmers never make explicit calls to start, commit, or abort a transaction. All the necessary calls are made behind the scenes by the MTS runtime.

Why is the attribute-based programming model better than the older procedural model, which requires explicit API calls? First, the new model requires less code. You indicate your preferences at design time by setting attributes, and the underlying runtime environment makes sure your needs are met. A second, less obvious reason is that administrators can easily reconfigure the way that an application uses a system service after it's been put into production. There's no need to modify any code or recompile your application.

The attribute-based programming model of MTS relies on a mechanism known as interception. When a client creates an object from a component that's been configured in an MTS application, the underlying runtime inserts an interception layer, as shown in Figure 1-7. This interception layer represents a hook that allows the MTS runtime to perform system-supplied preprocessing and postprocessing on method calls. The system steals away control right before and right after an object executes the code behind each method.

click to view at full size.

Figure 1-7 An attribute-based programming model relies on interception to leverage system services.

The COM vs. MTS problem

One of the biggest dilemmas for programmers who are building multitier applications targeted for Windows NT Server is deciding when to use COM versus MTS. Many companies have chosen MTS because it offers many valuable built-in services that COM doesn't offer. Other companies have chosen COM because they don't understand the added value of the MTS runtime environment.

COM ships with Windows NT Server, while MTS does not. To use MTS, you must install an extra piece of software, the Windows NT Option Pack. This means that MTS isn't really part of COM. COM has its own programming model and runtime layer; MTS has a different programming model and separate runtime layer.

You should see that MTS is simply a layer that has been built on top of COM. COM was never modified to accommodate MTS. So what does this mean? The two runtime layers aren't as tightly integrated as they could be. This results in a platform that contains a certain degree of inefficiency, ambiguity, and confusion. Things are tricky for MTS programmers because they need to know how both programming models work. Moreover, many valid COM programming techniques don't work correctly when used in an MTS application.

From COM and MTS to COM+

As the platform architects began planning changes and enhancements for Windows 2000, one thing was obvious: COM and MTS had to be unified into a single runtime layer and a single programming model. This wasn't a trivial undertaking, but it was well worth the effort.

With the release of Windows 2000, all the best ideas of COM and MTS have been integrated into a new runtime named COM+. Unlike MTS, this new runtime layer isn't optional. COM+ is part of the default installation of Windows 2000. But the good news is that the COM-versus-MTS dilemma doesn't exist on Windows 2000. Moreover, writing components for COM+ is easier than for MTS because many of the annoying idiosyncrasies associated with MTS have gone away.

Like COM, COM+ is based on binary components and interface-based programming. Method calls are remoted across process and computer boundaries through the use of a transparent RPC layer. And just like COM components, COM+ components can be upgraded and extended in production without adversely affecting the client applications that use them.

Like MTS, COM+ supports distributed transactions and role-based security. It provides a built-in thread-pooling scheme that's as transparent as the one for MTS. The COM+ programming model also uses interception to expose platform services to developers through declarative attributes. However, COM+ takes attribute-based programming much further than MTS. In addition to transaction services and integrated security, COM+ exposes services such as custom object construction, synchronization, and object pooling. Other new COM+ features, such as Queued Components and COM+ Events, are also exposed through configurable attributes.

Configured vs. nonconfigured components

If you want your components to take advantage of COM+ services, you must install them in a COM+ application. When a component is installed in a COM+ application, it's given a profile in a system catalog called the COM+ registration database (RegDB). This catalog holds configured attribute settings for components as well as for COM+ applications. A component that has been installed in a COM+ application is known as a configured component, primarily because it has associated COM+ attribute settings.

You'll also encounter an older type of component that doesn't have associated COM+ attributes: the nonconfigured component. Nonconfigured components aren't installed in COM+ applications. Instead, they are registered in a manner consistent with earlier versions of COM. Nonconfigured components can't take advantage of COM+ services, but they can run in environments other than MTS and COM+.

If you're authoring component code for a COM+ application, you'll generally produce configured components. This approach allows you to take advantage of various platform services. When you're writing your code, you're also likely to encounter nonconfigured components. For instance, the ActiveX Data Objects (ADO) library is made up of nonconfigured components. ADO objects can run in a COM+ application, but unlike configured components, they can also run in applications based on earlier versions of COM.



Programming Distributed Applications with COM+ and Microsoft Visual Basic 6.0
Programming Distributed Applications with Com and Microsoft Visual Basic 6.0 (Programming/Visual Basic)
ISBN: 1572319615
EAN: 2147483647
Year: 2000
Pages: 70
Authors: Ted Pattison

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net