[Zope-dev] make zope.component.registry.Components inherit from dict?
Chris McDonough
chrism at plope.com
Mon Nov 23 23:03:44 EST 2009
Matthew Wilkes wrote:
> Hi Chris,
>
> On 2009-11-24, at 0324, Chris McDonough wrote:
>
>> In repoze.bfg, we've actually decided to use a subclass of the component
>> registry which also inherits from "dict". This makes it possible to
>> spell
>> common unnamed "utility" registrations and lookups as:
>>
>> utility = SomeUtilityImplementation()
>> registry['someutility'] = utility
>
> While I'm all for simplification, this makes very little sense to me.
> If this is an unnamed registration why is there a name ('someutility')
> involved?
>
> If it was a named registration against Interface, or if the key was an
> interface/dotted name that'd make sense.
You may have Zope Component Developer's Eyes, a common disease in these parts. ;-)
If you haven't already, you might take a look at the example after the
paragraph that starts with "But we recognize that developers who my want to
extend the framework..." within:
<http://docs.repoze.org/bfg/1.1/designdefense.html#ameliorations>
> Could you expand on what the key is supposed to represent?
Sure. Let's take an example from repoze.bfg itself.
repoze.bfg allows an application developer to register a "root factory" for a
given application. There is only ever one of these for any application, and
thus only one ever needs to be registered.
For purposes of example, a root factory might be the "root" method of a
particular ZODB connection, e.g. "root = conn.root()". It's a callable that
returns the sole root object for a given application. For purposes of example,
let's pretend it's this:
def root_factory(environ):
return {}
Under the hood, the system does something like this when a root factory needs
to be registered:
from repoze.bfg.interfaces import IRootFactory
from zope.component import getSiteManager
reg = getSiteManager()
reg.registerUtility(root_factory, IRootFactory)
Then when the system needs to look it up again, it needs to do this:
root_factory = getUtility(IRootFactory)
If you notice, there is no "key" for this utility other than the IRootFactory
interface (it's unnamed). In this case, also, there will never be a
registration made against a subclass of IRootFactory. In this scenario, if we
weren't using ZCA at all, we'd probably do something like this:
reg = get_some_registry()
reg['root_factory'] = root_factory
In a system like this, there are no interfaces; the string 'root_factory'
performs the same job as the IRootFactory interface for registration and
lookup. I'd like to make the ZCA registry operate like this. There's really
no reason for there to be an interface hanging around to represent this thing:
we're using the ZCA as a complicated dictionary here.
It would also obviously be possible to just add a dictionary instance attribute
to a registry, so instead of subclassing Components from dict, you might do:
reg = getSiteManager()
reg.simple['root_factory'] = root_factory
To be honest, I don't mind one way or another; I'd just like to push whatever
we do upstream if possible. If we move too far away from the stock ZCA
facilities, it becomes harder to integrate Zope apps into BFG and vice versa.
- C
More information about the Zope-Dev
mailing list