COM Aggregation   «Prev  Next»
Lesson 4 Interface navigation
Objective Examine interface navigation issues under aggregation.

COM Interface Navigation

Before looking at the guidelines for implementing aggregation, let us examine interface navigation and reference counting issues in the context of aggregation.
Assume an outer object OuterCOMObj (the aggregator) implements interface IF1;
  1. an inner object InnerCOMObj
  2. (the aggregate) implements interface IF2.
Both the inner and the outer objects also implement IUnknown.


OuterCOMObj IF1 and InnerCOMObj IF2
OuterCOMObj IF1 and InnerCOMObj IF2

Recall that the COM specification states that, given an interface pointer into an object, a client must be able to get a pointer to any other interface implemented by the object.
Consider the following use scenarios in client COMCli:
Declares an HRESULT to use for COM return values.
  1. Declares an HRESULT to use for COM return values.
  2. Declares a pointer to interface IF1.
  3. The client creates an instance of OuterCOMObj, asking for a pointer to IF1. As part of its start-up sequence, OuterCOMObj creates an instance of InnerCOMObj. It next returns a pointer to IF1 to the client.
  4. Checks to return status of CoCreateInstance.
  5. The client calls IF1::QueryInterface asking for a pointer to IF2, an interface in InnerCOMObj.

Interface navigation

Interface navigation using HRESULT to use for COM return values.
Interface navigation using HRESULT to use for COM return values.

Line 1 Declares an HRESULT to use for COM return values.
Line 2 Declares a pointer to interface IF1.
Line 3 The client creates an instance of OuterCOMObj, asking for a pointer to IF1. As part of its start-up sequence, OuterCOMObj creates an instance of InnerCOMObj. It next returns a pointer to IF1 to the client.
Line 9 Checks to return status of CoCreateInstance.
Line 12 The client calls IF1::QueryInterface asking for a pointer to IF2--an interface in InnerCOMObj.


In terms of object reusability, the situation depicted above is easy to handle. The outer COM object can be explicitly coded to know that the inner COM object implements IF2. But now consider the following scenario in the client COMCli:

HRESULT to use for COM return values
  1. Declares an HRESULT to use for COM return values
  2. Declares a pointer to interface IF2.
  3. The client creates in instance of OuterCOMObj asking for a pointer to IF2. The client thinks IF2 is implemented in OuterCOMObj, that is, the aggregated component is not visible to the client. As part of its start-up sequence, OuterCOMObj creates an instance of InnerCOMObj asking for a pointer to IF2 that is returned to the client.
  4. Checks to return status of CoCreateInstance.
  5. The client calls IF2::QueryInterface asking for a pointer to IF2: an interface in OuterCOMObj. The client is not aware that the IF2::QueryInterface call is made into InnerCOMObj. It thinks it is calling into OuterCOMObj.

Interface navigation

Interface navigation
Interface navigation

Line 1 Declares an HRESULT to use for COM return values.
Line 2 Declares a pointer to interface IF2.
Line 3 The client creates in instance of OuterCOMObj asking for a pointer to IF2. The client thinks IF2 is implemented in OuterCOMObj,
that is, the aggregated component is not visible to the client. As part of its start-up sequence, OuterCOMObj creates an instance of InnerCOMObj asking for a pointer to IF2 that is returned to the client.
Line 9 Checks to return status of CoCreateInstance.
Line 12 The client calls IF2::QueryInterface asking for a pointer to IF2--an interface in OuterCOMObj. The client is not aware that the IF2::QueryInterface call is made into InnerCOMObj. It thinks it is calling into OuterCOMObj.

This code sequence is legal because the client thinks that OuterCOMObj implements both IF1 and IF2. The client expects a call to IF2::QueryInterface for IF1 to succeed because, from its perspective, OuterCOMObj implements both IF1 and IF2.
How can we code an inner object (that is, one that supports aggregation) to know about interfaces in an outer object? After all, when we develop an object, we do not normally know how it will be reused later on. The answer is, we do not have to write code in an inner object that has any knowledge of interfaces in the outer object. Once aggregation is set up correctly in the inner and outer objects, it will work.
This scenario illustrates one of the problems we must solve when aggregating objects: How can aggregated COM objects work with the outer COM object to support interface navigation? For aggregation to work, all the COM objects involved must act like one object. All objects participating in the aggregation must support interface navigation to any interface in any object in the aggregation. Before answering this question, let us examine reference counting issues within the context of aggregation.

Inside Microsoft Programming