1.1.6 Declaring Implementations and Adapters

There are three kinds of relationships that a protocol can participate in:

Each of these relationships is defined by a source (a type, instance or protocol), a destination (desired) protocol, and an adapter factory used to convert from one to the other. If no adapter is needed, we can say that the adapter factory is the special NO_ADAPTER_NEEDED function.

To declare relationships like these, the protocols declaration API provides three ``primitive'' declaration functions. Each accepts a destination protocol (that must support the IOpenProtocol interface), an adapter factory (or NO_ADAPTER_NEEDED), and a source (type, instance, or protocol). These three functions are declareAdapterForType(), declareAdapterForObject(), and declareAdapterForProtocol(), respectively.

You will not ordinarily use these primitives, however, unless you are customizing or extending the framework. It is generally easier to call one of the higher level functions in the declaration API. These higher-level functions may make several calls to the primitive functions on your behalf, or supply useful defaults for certain parameters. They are, however, based entirely on the primitive functions, which is important for customizations and extensions.

The next higher layer of declaration APIs are the explicit declaration functions: declareImplementation, declareAdapter, and adviseObject. These functions are structured to support the most common declaration use cases.

For declaring protocols related to a type or class:

declareImplementation( typ [, instancesProvide=[ ]][, instancesDoNotProvide=[ ]])

Declare that instances of class or type typ do or do not provide implementations of the specified protocols. instancesProvide and instancesDoNotProvide must be sequences of protocol objects that provide (or are adaptable to) the IOpenProtocol interface, such as protocols.Interface subclasses, or Interface objects from Zope or Twisted.

This function is shorthand for calling declareAdapterForType() with NO_ADAPTER_NEEDED and DOES_NOT_SUPPORT as adapters from the type to each of the specified protocols. Note, therefore, that the listed protocols must be adaptable to IOpenProtocol. See declareAdapterForType() in section 1.1.9 for details.

For declaring protocols related to a specific, individual instance:

adviseObject( ob [, provides=[ ]][, doesNotProvide=[ ]])
Declare that ob provides (or does not provide) the specified protocols. This is shorthand for calling declareAdapterForObject() with NO_ADAPTER_NEEDED and DOES_NOT_SUPPORT as adapters from the object to each of the specified protocols. Note, therefore, that ob may need to support IOpenProvider, and the listed protocols must be adaptable to IOpenProtocol. See declareAdapterForObject() in section 1.1.9 for details. Also, see section 1.1.6, ``Protocol Declarations for Individual Objects'', for more information on using adviseObject.

And for declaring all other kinds of protocol relationships:

declareAdapter( factory, provides, [, forTypes=[ ]][, forProtocols=[ ]][, forObjects=[ ]])

Declare that factory is an IAdapterFactory whose return value provides the protocols listed in provides as an adapter for the classes/types listed in forTypes, for objects providing the protocols listed in forProtocols, and for the specific objects listed in forObjects.

This function is shorthand for calling the primitive declaration functions for each of the protocols listed in provides and each of the sources listed in the respective keyword arguments.

Although these forms are easier to use than raw declareAdapterForX calls, they still require explicit reference to the types or objects involved. For the most common use cases, such as declaring protocol relationships to a class, or declaring an adapter class, it is usually easier to use the ``magic'' protocols.advise() function, which we will discuss next.



Subsections