Reputation: 8067
When I write some utility, register it and then query with getUtility
it works ok:
class IOperation(Interface):
def __call__(a, b):
''' performs operation on two operands '''
class Plus(object):
implements(IOperation)
def __call__(self, a, b):
return a + b
plus = Plus()
class Minus(object):
implements(IOperation)
def __call__(self, a, b):
return a - b
minus = Minus()
gsm = getGlobalSiteManager()
gsm.registerUtility(plus, IOperation, '+')
gsm.registerUtility(minus, IOperation, '-')
def calc(expr):
a, op, b = expr.split()
res = getUtility(IOperation, op)(eval(a), eval(b))
return res
assert calc('2 + 2') == 4
Now, as I understand I could move registration of utilities to the configure.zcml
, like this:
<configure xmlns="http://namespaces.zope.org/zope">
<utility
component=".calc.plus"
provides=".calc.IOperation"
name="+"
/>
<utility
component=".calc.minus"
provides=".calc.IOperation"
name="-"
/>
</configure>
But I don't know how to make globbal site manager read this zcml.
Upvotes: 0
Views: 383
Reputation: 8067
Actually, all that was needed to make this work - move parsing of zcml to another file. So, the solution now consists of three files:
calc.py
:
from zope.interface import Interface, implements
from zope.component import getUtility
class IOperation(Interface):
def __call__(a, b):
''' performs operation on two operands '''
class Plus(object):
implements(IOperation)
def __call__(self, a, b):
return a + b
class Minus(object):
implements(IOperation)
def __call__(self, a, b):
return a - b
def eval(expr):
a, op, b = expr.split()
return getUtility(IOperation, op)(float(a), float(b))
configure.zcml
:
<configure xmlns="http://namespaces.zope.org/zope">
<include package="zope.component" file="meta.zcml" />
<utility
factory="calc.Plus"
provides="calc.IOperation"
name="+"
/>
<utility
factory="calc.Minus"
provides="calc.IOperation"
name="-"
/>
</configure>
And main.py
:
from zope.configuration import xmlconfig
from calc import eval
xmlconfig.file('configure.zcml')
assert eval('2 + 2') == 4
Upvotes: 0
Reputation: 11337
You include it from some other ZCML file with
<include package="your.package" />
If you're writing an application from scratch, you'll have to have a top-level ZCML file
that first registers all the ZCML directives (e.g. <utility>
) by including the right meta.zcml
before you can use them in your own included ZCML files:
<include package="zope.component" file="meta.zcml" />
On the Python side, you use one of the APIs in the zope.configuration.xmlconfig module to load the ZCML file:
Which one? How are they different? I don't know! It's all supposedly documented, but I can't make heads or tails of it! I used xmlconfig.string
in ZODBBrowser, and it seems to work, but was that a good idea? I don't know!
Don't use Zope if you value your sanity.
Upvotes: 1