Tải bản đầy đủ (.pdf) (10 trang)

COM+ Context

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (567.68 KB, 10 trang )

A proxy application cannot export another MSI file. In fact, all the application-component, interface, and method-level settings
on a proxy application are disabled, except the Remote server name under the Activation tab. The Remote server name edit
box is disabled in library and server applications.
1.8.2 Installing and Uninstalling an Exported Application
The most common way to install an MSI file on another machine is simply to click on it, which will launch the Windows
Installer. The application files (DLLs and proxy/stubs) will be placed in a default location:
\Program Files\COMPlus Applications\{<the application's guid>}
If you wish to have the application installed in a different location, you must use the Component Services Explorer Application
Install Wizard. Bring up the wizard and select Install pre-built application(s). Browse to where the MSI file is stored, and select
it. The wizard will let you choose whether you want to use the default location for installation or specify a different one.
If you want to automate uninstalling COM+ applications, you can use a command line instruction to invoke the Windows
Installer to uninstall a COM+ application:
msiexec -x <application name>.msi
You can also use the Windows Control Panel's Add/Remove Programs applet to add or remove COM+ applications.
1.9 Summary
In this chapter, you created a trivial example COM component and implemented it in a DLL. You used it as an in-proc server
or as a local server and even controlled its life cycle and idle time management by configuring the component (actually its
containing application) differently. All this was achieved without changing a single line of code on the object or the client side.
This achievement reflects the power of COM+: it enables you to focus on your product and domain problems at hand, while
declaratively taking advantage of available services. The rest of this book discusses these services thoroughly, including their
interactions and pitfalls, and provides tips and tricks for how to apply them productively.
Chapter 2. COM+ Context
COM+ provides services to components by intercepting the calls the client makes to component interfaces. The idea of
providing services through an interception mechanism is not a COM+ innovation. As you will see, classic COM also provides
component services via interception. What is new is the length to which COM+ takes the idea. This chapter starts by
describing the way classic COM uses marshaling to provide its services and to encapsulate the runtime requirements of its
objects. Next, the chapter introduces you to the COM+ context—the innermost execution scope of an object. COM+ call
interception occurs at context boundaries. Generally, you need not be concerned with contexts at all. They are transparent to
you, whether you develop a client or a component. However, the COM+ context is a good model for explaining the way
COM+ services are implemented. This book clearly outlines the few cases when you should interact with the contexts directly.
Interaction with the contexts occurs mostly when dealing with COM+ instance management and transactions, but also when


dealing with some security issues.
2.1 Encapsulation via Marshaling in COM
One of the core principles of classic COM is location transparency. Location transparency allows the client code to be
independent of the actual object's location. Nothing in the client's code pertains to where the object executes, although the
client can insist on a specific location as well. A client CoCreates its objects and COM instantiates them in the client's process,
in another process on the client's machine, or on another machine altogether. COM decides where the objects will execute
based on a few Registry values. Those values are maintained outside the object code. A change in those values can cause the
same object to be activated in a different location. The same client code handles all cases of object location. You can say that
COM completely encapsulates the object location. A key idea in object-oriented and component-oriented programming is
encapsulation, or information hiding. Encapsulation promotes the design of more maintainable and extensible systems. By
ignoring the object location, the client code is decoupled further from the object. The client code does not need to be modified
if the object location changes. COM encapsulates the object location by introducing a proxy and stub between the object and
its client. The client then interacts with the object directly or through a proxy, and COM marshals the call from the client to
the object's true location, if it needs to (all three cases are shown in Figure 2-1). The important observation here is that the
Page 22 of 238
10/3/2002file://F:\Documents%20and%20Settings\Administrator\Local%20Settings\Temp\Rar$EX0...
client code is not required to make assumptions about the location of its called objects or to make explicit calls across
processes (using named pipes, for instance) or across machines (using sockets).
Figure 2-1. Classic COM completely encapsulates the object location from the client by introducing a proxy/stub between
them

To provide location transparency, COM proxies are polymorphic with the object; they support exactly the same set of
interfaces as the real object, so the client cannot tell the difference between the proxy and the real object.
Another time when classic COM encapsulates an object property using marshaling is in its handling of the object's
synchronization needs. The object's developer declares in the Registry what threading model the object uses. If an
incompatibility exists between the creating client-threading model and the object's threading model, COM puts a proxy and
stub between them and marshals calls from the client thread to the object thread. Since many threads can exist in a given
process, COM divides a process into apartments, and any call crossing an apartment boundary is marshaled (see Figure 2-2).
Again, the proxy and stub completely encapsulate the object's execution thread. The same client code can handle calling
methods on objects on the same thread (in the same apartment), on a different thread (in a different apartment) in the same

process, or on another thread in a different process. The proxy and stub are responsible for performing a thread context
switch when marshaling the call from the client thread to the object thread. Because the object needs to appear to the client
as though it is executing on the same thread as the client, the proxy and stub will also handle the required synchronization;
the proxy has to block the client thread and wait for the stub to return from the call on the object thread. COM concurrency
management makes it possible for the client to ignore the exact synchronization requirement of the object. A dedicated
synchronization protocol, such as posting messages between the client and the object, or signaling and waiting on events or
named events is not necessary. Because nothing in the client's code considers the object's threading need, when the object's
threading model changes (when a new version of the object with a new threading model is deployed), the client code remains
unchanged.
Figure 2-2. Classic COM encapsulates the object execution thread by inserting a proxy and a stub between the client and the
object
Page 23 of 238
10/3/2002file://F:\Documents%20and%20Settings\Administrator\Local%20Settings\Temp\Rar$EX0...

The two examples have a few things in common. The proxy intercepts calls from the client to the object, making sure the
object gets the runtime environment it requires to operate properly. The proxy and stub marshal away incompatibilities
between the client and the object, and they perform pre- and post-call processing, such as thread context switching, cross-
process communication, blocking the calling thread, and signaling internal events. In both examples, the object declares its
requirements in the Registry, rather than providing specific code for implementing them.
While classic COM provides only a few services by intercepting the client's calls, you can see the potential for implementing
additional services through this mechanism. Ideally, you could declare which services your component requires and then use
system component services instead of implementing them yourself. This is where COM+ comes in.
2.2 Encapsulation via Interception in COM+
COM+ provides its component services via interception. You can configure your component to take advantage of services, and
COM+ puts a proxy and stub between the component and its client, if the client and the component instance are incompatible
with any one of the services. It also puts a proxy and stub between them if a service requires interception, regardless of the
way the client and the object are configured. The exact object configuration is completely encapsulated by the proxy and stub
and the call interception. Nothing in the client code couples it to the object configuration. This development is a major step
toward ultimate encapsulation, in which the component contains almost nothing but business logic and in which the way it
uses component services such as transactions, security, events, and activation is hidden from the client. Similarly, the

component does not care about its client configuration, as the two do not need to interact with each other about the way they
use the services.
Because an object can have the same threading model as its creating client while differing in other service configuration,
apartments can no longer be the innermost execution scope of an object. Instead, COM+ subdivides apartments, so each
object can be placed in a correct runtime environment appropriate to its needs and intercept all calls to the object. The
subdivision of an apartment into units of objects that share the same configuration is called a context. Each apartment has
one or more contexts, and a given context belongs to exactly one apartment. A context can host multiple objects, and each
object belongs to exactly one context. Figure 2-3 shows an example of how processes and apartments can be broken down
into contexts under COM+.
Figure 2-3. COM+ subdivides apartments into contexts
Page 24 of 238
10/3/2002file://F:\Documents%20and%20Settings\Administrator\Local%20Settings\Temp\Rar$EX0...

Because a COM+ object must belong to exactly one context, every apartment has at least one context and potentially many
more. There is no limitation to the number of contexts an apartment can host. All calls in and out of a context must be
marshaled via a proxy and stub so that COM+ can intercept the calls and provide configured services. This idea is similar to
the classic COM requirement that all cross-apartment calls be marshaled so that COM can enforce threading model
configurations. Objects in the same context can have direct pointers to one another, because they are configured to use the
same set of services in a way that allows same-context activation, and hence, direct access. Mediating between objects in the
same context is not necessary.
2.2.1 Lightweight Proxies
When COM+ marshals a call between two contexts in the same apartment, it does not need to perform a thread context
switch. However, COM+ still puts a proxy and stub in place to intercept the call from the client to the object and perform a
service context switch. This switch ensures that the object gets the runtime environment it requires. COM+ uses a new kind of
proxy for this marshaling: a lightweight proxy. It is called a lightweight proxy because no expensive thread context switch is
needed to marshal calls from the client to the object. The performance hit for a service context switch is a fraction of that
incurred when performing a thread context switch. A service context switch can sometimes be as lightweight as simply
checking the value of a flag, but usually it involves some pre- and post-call processing to marshal away differences in the
runtime environment between the client and the object.
The lightweight proxies are not the standard proxies used for cross-apartment/process/machine calls. Standard proxies are

either created using the MIDL compiler or provided by the standard type library marshaler. For a service switch, COM+
generates the lightweight proxies on the fly, at runtime, based on the exact object configuration. A lightweight proxy, like any
other proxy, presents the client with the exact same set of interfaces as those found on the actual object. COM+ provides the
lightweight proxy with the right interface signatures based on the type library embedded in the component's DLL.
An example for a lightweight proxy is a proxy that provides calls synchronization to the object. If the object is configured to
require synchronization (to prevent access by multiple concurrent threads), but its client does not require synchronization,
COM+ puts a lightweight synchronization proxy between the two. Another example is security. If the object is configured to
require an access check before accessing it, verifying that the caller was granted access to the object, but its client does not
care about security, there will be a lightweight security proxy in between. This proxy makes sure that only authorized callers
are allowed access to the object
If the object is in a different context from that of its caller because of incompatibility in just one component service (or if a
service always mandates a separate context), there will be just one lightweight proxy between the caller and the object.
Therefore, what should COM+ do if the client and the object differ in more than one service? The exact way the lightweight
proxies mechanism is implemented is not documented or widely known. However, in this case, COM+ probably does not
generate just one lightweight proxy to do multiple service switches, but rather puts in place as many lightweight proxies as
needed, one for every service switch. For example, consider an object that implements the interface IMyInterface and is
configured to use two COM+ services: Service A and Service B. If the client does not use Service A and Service B, COM+ puts
two lightweight proxies in place, as shown in Figure 2-4. The lightweight proxy to Service A only knows how to do a Service A
switch, and the lightweight proxy to Service B only knows how to do a Service B switch. Both services support the
IMyInterface

interface, and would delegate the client call from the first proxy to the second, to the object, and then back again. The net
result is that when the client calls into the context where the object resides, the object gets the correct runtime environment it
requires to operate. If the client and the object both use Service C, no lightweight proxy to Service C is required. (Stubs have
Page 25 of 238
10/3/2002file://F:\Documents%20and%20Settings\Administrator\Local%20Settings\Temp\Rar$EX0...
been removed from Figure 2-4 for clarity.)
Figure 2-4. Lightweight proxies perform service switches

2.2.2 Assigning Objects to Contexts

When a client calls
CoCreateInstance( )
(
New
or
CreateObject( )
, in Visual Basic), asking for a new instance of a configured
component (an object), COM+ first constructs the object and then decides which context to place the object in. In COM+
terminology, COM+ decides in which context to activate the object. COM+ bases its decision on two factors: the component's
configuration and the configuration of its creating client. Obviously, it would be best if the object could share a context with
the client. Doing so would obliterate the need for COM+ to marshal calls from the client to the object, and thus avoid having
to pay even the slight performance penalty of lightweight proxies.
COM+ examines the newly created object's configuration in the COM+ catalog and compares it with the configuration (or
rather, the context attributes) of the creating client. If the client's context can provide the object with a sufficient runtime
environment for its configuration, COM+ places the object in the client's context.
If, on the other hand, the client's context cannot provide the object with its required runtime environment, COM+ creates a
new context, places the object in it, and puts lightweight proxies between the two contexts. Note that COM+ does not try to
find out if another appropriate context for the object in that apartment already exists. The algorithm is simple—the object
either shares its creator's context or gets a new context. Obviously, the precondition for same-context activation is having a
compatible threading model between the client and the object. Otherwise, the object is placed in a different apartment, and
hence, a different context by definition, since a context belongs to exactly one apartment.
Classic COM components (nonconfigured components) do not rely on COM+ services to operate and do not require
lightweight proxies to mediate between their client runtime environment and their own. If a nonconfigured component can
share the same apartment as its creating client (compatible threading model), it will also share its context, and the client will
get a direct pointer to it, instead of a proxy. However, if the nonconfigured object requires a different apartment, it is placed
in a suitable apartment, in what is known as the default context. Each apartment has one default context used for hosting
nonconfigured components. The default context is defined mostly for COM+ internal consistency (every object must have a
context), and no lightweight proxies are used when objects in other contexts (in the same apartment) access it.
You can sum up the COM+ algorithm for allocating objects to contexts with this rule: a configured component is usually
placed in its own context, and a nonconfigured component shares its creator's context.

2.3 The Context Object
COM+ represents each context by an object called the context object. Every context has exactly one context object. Objects
can obtain a pointer to their context object by calling CoGetObjectContext( ) (see Figure 2-5). All objects in the same context get
the same context object.
CoGetObjectContext( ) is defined as:
Figure 2-5. By calling CoGetObjectContext( ), objects can get a pointer to their context's context object
Page 26 of 238
10/3/2002file://F:\Documents%20and%20Settings\Administrator\Local%20Settings\Temp\Rar$EX0...

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×