So, Monikers

In light of this problem, it makes sense that new names are themselves components that play by the same rules as all other components. Instead of these names being mere repositories for persistent data (the name data), they must also encapsulate the intelligence to work with that name behind a standard interface. Thus, all clients only need to include code to work with the standard name interface, not with each particular type of name. The solution is a persistent, intelligent name—a moniker.

A moniker encapsulates all of its capabilities behind the IMoniker interface, which includes both binding methods and persistence methods (from IPersistStream). Clients only need to know how to use the IMoniker member functions, and because all objects that implement the same interface are polymorphic, all monikers are polymorphic as well. Clients that know how to use one moniker know how to use all monikers.

Let this sink in for just a moment. Yes, I mean lift your eyes from this page and stare at the wall while you think about what this encapsulation means. You're still reading, aren't you? I'll stop writing for a minute.

Again, the problem with unintelligent names is that adding a new type of unintelligent name into a system means that only those clients updated to understand that new name can take advantage of it. With monikers, however, clients that know how to work with existing monikers can immediately and transparently work with any new moniker—with any new intelligent name—that is added to the system. A new name requires absolutely no changes whatsoever to existing clients. In short, OLE's naming and binding is extensible in all directions, requiring no changes to clients nor of the programming model.