Comment 1 for bug 240631

Revision history for this message
Philipp von Weitershausen (philikon) wrote : Re: [Bug 240631] [NEW] Impossible to determine how a utility was registered

Wichert Akkerman wrote:
> GenericSetup provides a way in Zope2 to manage local utilities. At the
> moment it is impossible to do this reliably since it can not detect if
> the current registration is similar to requested registration details,
> and just re-registering utilities will lead to loss of data in
> persistent utilities.

I don't understand why there would be data loss. You don't have to
reinstantiate an object just to re-register it (see below). You *do*
probably want to un-register first before re-registering in case
registration details changed (e.g. the name or provided interface).

> In order to support this cleanly there should be a query interface that
> allows one to get the registration information from the CA.

There is. Every component registry (aka site manager) supports the
following methods from zope.component.interfaces.IComponentRegistry:

* registeredUtilities()
* registeredAdapters()
* registeredSubscriptionAdapters()
* registeredHandlers()

They each return an iterable of zope.component.interfaces.IRegistration
objects which contain all the necessary information about how each
component was registered. Specific interfaces like IUtilityRegistration
tell you how to talk to those objects. E.g.:

   sm = cmf_site.getSiteManager()
   for reg in sm.registeredUtilities():
       print "%r was registered for %r as %r" (reg.component,
reg.provided, reg.name)

> As far as I could tell at the moment one can only do a query, which, for example,
> makes it impossible to determine if a factory was registered.

Utilities are *never* registered by factory. Sure, the <utility /> ZCML
directive takes a 'factory' argument, but if you use that instead of the
'component' argument, the directive handler will simply call the factory
and obtain the utility object, which is then registered.

Local persistent utilities are *always* registered as instances. In
other words, there's a persistent object somewhere that you then
register with the component registry.