Go Up to COM Servers
Sometimes, a server object makes use of another COM object to perform some of its functions. For example, an inventory management object might make use of a separate invoicing object to handle customer invoices. If the inventory management object wants to present the invoice interface to clients, however, there is a problem: Although a client that has the inventory interface can call QueryInterface to obtain the invoice interface, when the invoice object was created it did not know about the inventory management object and can't return an inventory interface in response to a call to QueryInterface. A client that has the invoice interface can't get back to the inventory interface.
To avoid this problem, some COM objects support aggregation. When the inventory management object creates an instance of the invoice object, it passes it a copy of its own IUnknown interface. The invoice object can then use that IUnknown interface to handle any QueryInterface calls that request an interface, such as the inventory interface, that it does not support. When this happens, the two objects together are called an aggregate. The invoice object is called the inner, or contained object of the aggregate, and the inventory object is called the outer object.
Note: In order to act as the outer object of an aggregate, a COM object must create the inner object using the Windows API CoCreateInstance or CoCreateInstanceEx, passing its IUnknown pointer as a parameter that the inner object can use for QueryInterface calls.
In order to create an object that can act as the inner object of an aggregate, it must descend from System.TContainedObject. When the object is created, the IUnknown interface of the outer object is passed to the constructor so that it can be used by the QueryInterface method on calls that the inner object can't handle.