[Zope3-dev] EventService, references, and subscription semantics

Steve Alexander steve@cat-box.net
Tue, 26 Feb 2002 20:13:15 +0000


I think I understand this problem better now.

Shane and I had a chat on IRC, and thrashed out various things, 
including the fact that I'd misunderstood how getAdapter works.

(See my message "object arg overloaded in IAdapterService.getAdapter")

Let's say we've got an ObjectHub (let's call it "hub") that wants to get 
a reference for an object "object".

The fact that hub is an ObjectHub doesn't matter.

The hub as the object passed to its register(object) method, and it 
wants to get an IReference for the object. Here's one way it could do so:

   def register(self, object):

       # get an IReferenceGenerator utility placefully
       # from the context of the object
       reference_generator = getUtility(object, IReferenceGenerator)

       # get an IReference from the reference generator
       # for the object
       reference = reference_generator(object)

I'm assuming interfaces like this (ignoring hashability etc.):

   class IReference(Interface):
       def dereference():
           """returns the object this reference refers to"""

   class IReferenceGenerator(Interface):
       def __call__(object):
           """returns an IReference for the given object"""


So, in Zope 3, we can install an IReferenceGenerator at appropriate 
branches of the object heirarchy, to take care of generating appropriate 
references for the objects below them (ie in their context).

Outside of Zope 3, we just have a global UtilitiesService, and a single 
global reference generator, that can be configured with whatever smarts 
it needs.

Now, it seems attractive to be able to, in a component such as hub, ask 
for an adapter, because we've got an object, and we want a particular 
interface that relates to that object. In fact, this isn't really 
adapter territory, as the reference we get is most likely not based on 
the interface of the object we want it for, but rather the 
location/context of the object we want it for.

Anyhow, if we still do want an anything-->IReference adapter, then we 
can easily build this on top of the IReferenceGenerator utility.

The register() method of hub would look like this:

   def register(self, object):

       # get an IReference that is appropriate to object
       reference = getAdapter(object, IReferenceGenerator)


This would be implemented by an adapter-maker registered for 
anything-->IReference, like this:

   def ireference_maker(context_component):
       reference_generator =  getUtility(context_component,
                                         IReferenceGenerator)
       reference = reference_generator(context_component)
       return reference


How does this sound?

--
Steve Alexander