Zope实用程序的ZCML注册可以接受组件或工厂,这有点令人困惑。
<utility component=".some.Class" />
与
<utility factory=".some.Factory" />
有什么区别?
答案 0 :(得分:3)
我认为@ lennart-regebro的答案可能有点无意中具有欺骗性。这是可以理解的,因为zope文档有点模糊。我认为以下是正确的解释,但我必须自己测试才能确定。
在组件和工厂注册每次后续调用到初始注册后,将返回相同实例。< / p>
不同之处在于组件方法会将引用的对象注册为要返回的实用程序实例,而工厂方法将调用引用的对象并将结果存储为要返回的实用程序实例。
因此,例如,如果您有一个如此定义的实用程序类;
class MyUtility(object):
implements(IMyUtility)
...
注册;
<utility factory=".my_module.MyUtility"/>
将在执行zcml时创建一个MyUtility实例,并将其存储以供将来调用getUtility;
> a = getUtility(IMyUtility)
> b = getUtility(IMyUtility)
> c = getUtility(IMyUtility)
> a is b is c
True
请注意,我们可以将工厂注册为函数而不是类,它只需要在没有参数的情况下调用时返回您要使用的实用程序实例。
组件的等效示例是;
class MyUtility(object):
implements(IMyUtility)
...
my_module_instance_of_utility = MyUtility()
注册;
<utility component=".my_module.my_module_instance_of_utility"\>
这或多或少等同于工厂示例。唯一的区别是组件示例中返回的实例在任何事物(包括注册机制)导入my_module
时实例化,其中当使用工厂时,实例在执行zcml配置时实例化,就在之前它已注册。在这两种情况下,后续的getUtility调用都将返回相同的实例。
这一切都不会与IFactory混淆,后者确实提供了一些东西,可以在每次要求时为您提供一个新实例,但API略有不同。请参阅this document for more information about those。
答案 1 :(得分:2)
工厂创建实用程序,而注册为组件的实用程序是实例。因此,如果您查找注册为组件的实用程序,则每次都会返回相同的对象。但如果它被注册为工厂,你每次都会得到一个新实例。