[Zope3-dev] Providing flexible adapters

Steve Alexander steve@cat-box.net
Tue, 26 Feb 2002 09:30:16 +0000


If only there were not the constraint on the Adapter Service that you 
provide an adapter between two particular interfaces...

Otherwise, I think what I've called IReferenceGenerator, below, is 
really just a matter of registering an adapter to provide an IReference 
for anything that it is given.

I can think of other scenarios where I'd want to provide generated 
adapters, such as using TransWarp (or another generative programming 
tool) with Zope 3.

Here's how I'd like to change the IAdapterService interface.
This is what we have now. I've shortened the docstrings.

class IAdapterService(Interface):

     def provideAdapter(forInterface, providedInterface, maker):
         "Provide an adapter"

     def getAdapter(object, interface, default=None):
         "Look up an adapter that provides an interface for an object"


I'd like to either

   * Split this into two interfaces: a getter and a mutator

   * Add a method for providing flexible adapters

An example of such a method is:

     def provideFlexibleAdapter(forInterface, maker):
         """Provide an adapter that can provide "forInterface" objects
            for a variety of provided interfaces"""

Or, we could keep the same provideAdapter method, and say that if None 
is given for providedInterface, we are providing a flexible adapter.

This could be implemented by a small specialisation of the IToIRegistry.
If the IToIRegistry finds no better match for (ob_interface, provide), 
it returns the match for (ob_interface, None), if there is one.


Then again, perhaps this is just a Utility rather than an adapter...
It looks similar to a utility by the way it is provided, but it provides 
the service of adapting an object to a particular interface. Hmm... I 
think it is still a kind of adapter.



Steve Alexander wrote:
>
> So, object Baz gets the LDAP Principal Object (let's call it "user"). It 
> wants to store a reference to user. Baz might well be an IEventService, 
> or other kind of ISubscribable object.
> 
>   1: Baz gets the IReferenceGenerator service
> 
>   2: Baz passes user to the IReferenceGenerator service
> 
>   3: If user implements IReference, the IReferenceGenerator service
>      simply returns user as its own IReference.
> 
>   4: Otherwise, the IReferenceGenerator service examines user's context
>      wrapper, and walks the wrapper looking for an
>      IReferenceGeneratorForContext utility.
> 
>   5: The IReferenceGenerator service passes user to the
>      IReferenceGeneratorForContext utility, which returns an appropriate
>      IReference object.
> 
>   6: If the IReferenceGeneratorForContext service returns None, or if it
>      can't be found, the IReferenceGenerator service does whatever it
>      is configured (by zcml directives perhaps) to do, such as return
>      a simple default IReference for the object.

--
Steve Alexander