Description
Utility design pattern in Zope 3 allows easily overridable singleton class instances for your code.
Read more in
Utilities can be
Local utilities are registered to persistent object. The context of local utilities is stored in a thread local variable which is set during the traversing. Thus, when you ask for local utilities, they usually come from persistent registry set up in the Plone site root object.
Global utilities are registered in ZCML and affect all Zope application server and Plone site instances.
Some hints:
<Moo^_^> what's difference between gsm.queryUtility() (global site manager) and zope.component.queryUtility()
<agroszer> Moo^_^, I think gsm... takes the global registrations, z.c.queryUtility respects the current context
Utility is constructed when Plone is started and ZCML is read. Utilities take no constructor parameters. If you need to use parameters like context or request, consider using views or adapters instead. Utilities may or may not have a name.
ZCML example:
<!-- Register header animation picking logic - override this for your custom logic -->
<utility
provides="gomobile.convergence.interfaces.IConvergenceMediaFilter"
factory=".filter.ConvergedMediaFilter" />
Python example (named utility):
def registerOnsitePaymentProcessor(processor_class):
""" """
# Make OnsitePaymentProcessor class available as utiltiy
processor = processor_class()
gsm = component.getGlobalSiteManager()
gsm.registerUtility(processor, interfaces.IOnsitePaymentProcessor, processor.name)
The utility class "factory" is in its simplest form a class which implements the interface:
class ConvergedMediaFilter(object):
""" Helper class to deal with media state of content objects.
"""
zope.interface.implements(IConvergenceMediaFilter)
def foobar(x):
""" An example method """
return x+2
Class is constructed / factory is run during the ZCML initialization.
To use this class:
from gomobile.convergence.interfaces import IConvergenceMediaFilter
def something():
filter = getUtility(IConvergenceMediaFilter)
x = filter.foobar(3)
Warning
Local utilities are potentially destroyed on the add-on product reinstall. Do not use them to store any data.
If you want to override any existing utility you can re-register the utility in overrides.zcml file in your product.
There are two functions
- zope.component.getUtility will raise exception if utility is not found
- zope.component.queryUtility will return None if utility is not found
Utility query parameters are passed to the utility class constructor.
Example:
from zope.component import getUtility, queryUtility
# context and request are passed to the utility class constructor
# they are optional and depend on the utility itself
picker = getUtility(IHeaderAnimationPicker, context, request)
Note
You cannot use getUtility() on Python module body level code during import, as Zope Component Architecture is not yet initialized. Always call getUtility() from HTTP request end point or after Zope has been started.
Query local + global utilities:
``zope.component.queryUtility()`` for local utilities, with global fallback.
Query only global utilities:
from zope.app import zapi
gsm = zapi.getGlobalSiteManager()
return gsm.getUtility(IConvergenceMediaFilter)
Warning
Due to Zope component architecture initialization order, you cannot call getUtility() in module level Python code. Module level Python code is run when the module is being imported, and Zope components are not yet necessary set up in this point.
Use zope.component.getUtilitiesFor().
Example
def OnsitePaymentProcessors(context):
""" List all registered on-site payment processors.
Mostly useful for validating form input.
Vocabulary contains all payment processors, not just active ones.
@return: zope.vocabulary.SimpleVocabulary
"""
utilities = component.getUtilitiesFor(interfaces.IOnsitePaymentProcessor)
for name, instance in utilities:
pass
The source code of this file is hosted on GitHub. Everyone can update and fix errors in this document with few clicks - no downloads needed.
For basic information about updating this manual and Sphinx format please see Writing and updating the manual guide.