One of the most useful features of monikers is that you can concatenate or compose monikers together. A composite moniker is a moniker that is a composition of other monikers, and can determine the relation between the parts. This lets you assemble the complete path to an object given two or more monikers that are the equivalent of partial paths. You can compose monikers of the same class (like two file monikers) or of different classes (like a file moniker and an item moniker). If you were to write your own moniker class, you could also compose your monikers with file or item monikers. The basic advantage of a composite is that it gives you one piece of code to implement every possible moniker that is a combination of simpler monikers. That reduces tremendously the need for specific custom moniker classes.
Because monikers of different classes can be composed with one another, monikers provide the ability to join multiple namespaces. The file system defines a common namespace for objects stored as files because all applications understand a file-system path name. Similarly, a container object also defines a private namespace for the objects that it contains, because no container understands the names generated by another container. Monikers allow these name spaces to be joined because file monikers and item monikers can be composed. A moniker client can search the namespace for all objects using a single mechanism. The client simply calls IMoniker::BindToObject on the moniker, and the moniker code handles the rest. A call to IMoniker::GetDisplayName on a composite creates a name using the concatenation of all the individual monikers' display names.
Furthermore, because you can write your own moniker class, moniker composition allows you to add customized extensions to the namespace for objects.
Sometimes two monikers of specific classes can be combined in a special way. For example, a file moniker representing an incomplete path and another file moniker representing a relative path can be combined to form a single file moniker representing the complete path. For example, the file monikers c:\work\art could be composed with the relative file moniker ..\backup\myfile.doc to equal c:\work\backup\myfile.doc. This is an example of "non-generic" composition.
"Generic" composition, on the other hand, permits the connection of any two monikers, no matter what their classes. For example, you could compose an item moniker onto a file moniker, though not, of course, the other way around.
Because a non-generic composition depends on the class of the monikers involved, its details are defined by a the implementation of a particular moniker class. You can define new types of non-generic compositions if you write a new moniker class. By contrast, generic compositions are defined by OLE. Monikers created as a result of generic composition are called generic composite monikers.
These three classes — file monikers, item monikers, and generic composite monikers — all work together, and they are the most commonly used classes of monikers.
Moniker clients should call IMoniker::ComposeWith to create a composite on moniker with another. The moniker it is called on internally decides whether it can do a generic or non-generic composition. If the moniker implementation determines that a generic composition is usable, OLE provides the CreateGenericComposite API function to facilitate this.