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:

By calling CoGetObjectContext( ), objects can get a pointer to their context’s context object

Figure 2-5.  By calling CoGetObjectContext( ), objects can get a pointer to their context’s context object

HRESULT CoGetObjectContext(REFIID riid, void** ppInterface);

The context object supports a few interfaces, so the first parameter of CoGetObjectContext( ) is always an IID that specifies which interface to retrieve. Two of the context object’s interfaces, IObjectContext and IObjectContextActivity, are legacy interfaces from MTS and are provided primarily for backward compatibility with MTS components running under COM+. The other two interfaces, IContextState and IObjectContextInfo , are specific to COM+. Throughout this book, all chapters use these two interfaces, rather than the legacy MTS interfaces.

The IContextState interface controls object deactivation (discussed in Chapter 3) and transaction voting (discussed in Chapter 4) by manipulating state bits in the context object.

IObjectContextInfo gains access to various aspects of the current transaction, retrieves the current activity ID (discussed in Chapter 5), and retrieves the current context ID. The IObjectContextInfo interface is defined as:

interface IObjectContextInfo : IUnknown 
{
   BOOL IsInTransaction(  );
   HRESULT GetTransaction([out]IUnknown** ppTransaction);
   HRESULT GetTransactionId([out]GUID* pTransactionId);
   HRESULT GetActivityId([out]GUID* pActivityId);
   HRESULT GetContextId([out]GUID* pContextId);
};

Every COM+ context has a unique ID (a GUID) associated with it. Retrieving the current context ID is sometimes useful for tracing and debugging purposes. Example 2-1 shows how to trace the current context ID by calling CoGetObjectContext( ), requesting the IObjectContextInfo interface, and then calling the IObjectContextInfo::GetContextId( ) method.

Example 2-1. Retrieving the current context ID with IObjectContextInfo::GetContextId( )

HRESULT hres = S_OK;
IObjectContextInfo* pObjectContextInfo = NULL;
GUID guidContextID = GUID_NULL;
   
hres =::CoGetObjectContext(IID_IObjectContextInfo,(void**)&pObjectContextInfo);
ASSERT(pObjectContextInfo != NULL);//not a configured component? 

hres = pObjectContextInfo->GetContextId(&guidContextID);
pObjectContextInfo->Release(  );

USES_CONVERSION;
WCHAR pwsGUID[150];
::StringFromGUID2(guidContextID,pwsGUID,150);
TRACE("The object is in context with ID %s",W2A(pwsGUID));

Tip

Note that only COM+-configured components should call CoGetObjectContext( ). When a nonconfigured component calls CoGetObjectContext( ), the call will fail with the return value of E_NOINTERFACE, and the returned interface pointer will be set to NULL. The assertion check in Example 2-1 tests for that condition.

One more point regarding the context object: the context object and its interfaces are private to the specific context they represent and should not be shared with or passed to objects in other contexts. Doing so may introduce hard-to-detect bugs and nondeterministic behavior of object deactivation and destruction, and it may affect transaction semantics and accuracy.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset