[Zope3-checkins] CVS: Zope3/src/zope/app/services - utility.txt:1.2

Jim Fulton jim@zope.com
Sun, 22 Jun 2003 21:02:19 -0400


Update of /cvs-repository/Zope3/src/zope/app/services
In directory cvs.zope.org:/tmp/cvs-serv26525

Modified Files:
	utility.txt 
Log Message:
Made various small improvements.


=== Zope3/src/zope/app/services/utility.txt 1.1 => 1.2 ===
--- Zope3/src/zope/app/services/utility.txt:1.1	Sun Jun 22 09:28:17 2003
+++ Zope3/src/zope/app/services/utility.txt	Sun Jun 22 21:02:18 2003
@@ -128,35 +128,33 @@
 
 We'll start by updating the utility service to support registrations.
 The updated local utility service implementation can be found in
-zope/app/services/utility.py.
+``zope/app/services/utility.py``. It's a good idea to refer to the
+source file as you read the description here.
 
 First, we'll pick a data structure.  We'll use a persistent dictionary
 mapping utility names to implementor registries.  An implementor
-registry implements a mapping from interfaces to objects; it's not
-quite the same as a mapping because it understands subclassing
-relationships between the interfaces used as keys.  In this case, the
-implementor registries themselves map interfaces to
-RegistrationStacks::
+registry implements a mapping from interfaces to objects; it's a
+special mapping because it understands subclassing relationships
+between the interfaces used as keys.  In this case, the implementor
+registries themselves map interfaces to RegistrationStacks. The
+overall data structure looks like::
 
   { utility_name -> { interface -> stack } }
 
-
 We also need to implement
-zope.app.interfaces.services.registration.IRegistry.  This defines two
-methods, ``queryRegistrationsFor`` and ``createRegistrationsFor``.
-
-A ``queryRegistrationsFor`` method is added to implement
-``IRegistry``.  It takes a registration object and returns the
-corresponding registration registry.  The registration object is
-used to provide an abstract way to represent registration parameters.
-Typically, the registration parameters are extracted and a more
-concrete method is called.  In the local utility service, we extract
-the utility name and interface and call ``queryRegistrations`` with
-the name and interface.
+``zope.app.interfaces.services.registration.IRegistry``.  This defines
+two methods, ``queryRegistrationsFor`` and ``createRegistrationsFor``.
+The ``queryRegistrationsFor`` method takes a registration object and
+returns the corresponding registration stack.  The registration
+object is used to provide an abstract way to represent registration
+parameters.  Typically, the registration parameters are extracted and
+a more concrete method is called.  In the local utility service, we
+extract the utility name and interface and call ``queryRegistrations``
+with the name and interface.
 
-Similarly, we add a ``createRegistrationsFor`` method that takes a
+Similarly, the``createRegistrationsFor`` method takes a
 registration object holding registration parameters and creates a
-registration registry for the parameters (if none already exists).
+registration stack for the parameters (if none already exists).
 If we don't have a implementor registry for a utility name, we create
 one and add it.  When we create the implementor registry, we pass a
 ``PersistentDict`` for it to use to store registration data.  This
@@ -164,17 +162,17 @@
 data for the given interface, we create a registration registry and
 register it for the interface.
 
-Finally, we modify ``queryUtility`` to use registered utility
-registrations.  We try to get a registration registery by calling
-``queryRegistrations``.  If we get one, we call its ``active``
-method to get the active registration, if any.  Finally, we call
-``getComponent`` on the active registration to get the actual
-component.  We leave it up to the registration object to take care of
-actually finding and returning the component.
-
-We need to provide utility registration objects.  The
-utility registration objects need to manage several bits of
-information:
+Finally, we modify ``queryUtility`` to use registered utilities.  We
+try to get a registration stack by calling ``queryRegistrations``.  If
+we get one, we call its ``active`` method to get the active
+registration, if any.  Finally, we call ``getComponent`` on the active
+registration to get the actual component.  We leave it up to the
+registration object to take care of actually finding and returning the
+component.
+
+In addition to the utility service, We need to provide utility
+registration objects.  The utility registration objects need to manage
+several bits of information:
 
 - name
 
@@ -185,29 +183,30 @@
 - The location of the actual component.
 
 The registration objects provide access to the component through the
-getComponent method.
+``getComponent`` method.
 
 To create the registration class, we'll start by defining a
-registration schema in
-``zope/app/interfaces/services/utility.py``.  The schema should extend
-``zope.app.interfaces.services.registration.IRegistration``.
-There's a more specific interface,
+registration schema in ``zope/app/interfaces/services/utility.py``.
+The schema should extend
+``zope.app.interfaces.services.registration.IRegistration``.  There's
+a more specific interface,
 ``zope.app.interfaces.services.registration.IComponentRegistration``
-that is much closer to what we need.  (XXX Add footnote explaining why
-we can't use INamedComponentRegistration in this example.)
-We extend this interface as IUtilityRegistration, which adds a name
-field (which is required but may be empty -- note the subtle
-difference, because the empty string is still used as part of the
-lookup key) and an interface field.  We also override the
-componentPath field to make it read-only (this is for the UI
-definition).
+that is much closer to what we need. [2]_ We extend this interface as
+IUtilityRegistration, which adds a name field (which is required but
+may be empty -- note the subtle difference, because the empty string
+is still used as part of the lookup key) and an interface field.  We
+also override the componentPath field to make it read-only (this is
+for the UI definition).
 
 A ``UtilityRegistration`` class is added to the ``utility`` module in
 ``zope/app/services`` that implements the registration interface.  We
-can subclass ComponentRegistration, which does much of the work.  Note
-that registration component includes two methods, defined in
+can subclass ComponentRegistration, which does much of the work.  The
+class definition includes a ``serviceType`` attribute. This attribute
+is used by the registration framework to decide which service a
+registration is used with.  The class includes two methods, defined in
 ``IRegistration``, giving summary information used by several
-predefined views.  See the interface for a description of these methods.
+predefined views.  See the interface for a description of these
+methods.
 
 We need to provide user interfaces for:
 
@@ -355,3 +354,11 @@
 
 .. [1] Of course, I initially forgot to include a nearly empty
    ``__init__.py`` file and had to add one later.
+
+.. [2] It's tempting to use ``INamedComponentRegistration`, but
+   ``INamedComponentRegistration`` is based on ``INamedRegistration``,
+   which is for registring components looked up by name alone.
+   ``INamedRegistration`` requires a non-empty name, but we want to
+   allow empty names, as we are looking up objects based on **both**
+   name and interface.
+