使用工厂定义的 Zope 实用程序与使用组件定义的 Zope 实用程序有什么区别?
-
22-09-2019 - |
题
Zope 实用程序的 ZCML 注册可以接受组件或工厂,这有点令人困惑。
<utility component=".some.Class" />
相对
<utility factory=".some.Factory" />
有什么不同?
解决方案
一个工厂的创建公用事业,而登记作为成分的效用是一个实例。因此,如果你看看注册为组件实用,你每次都会得到相同的对象回来。但是,如果它注册为一个工厂,你每一次得到一个新的实例。
其他提示
我认为@lennart-regebro 的回答可能无意中有点欺骗性。这是可以理解的,因为 zope 文档有点模糊。我认为以下是正确的解释,但我必须亲自测试才能确定。
在 组件和工厂 登记 随后的每个调用 初始注册后, getUtility 将返回 同一实例.
不同之处在于,组件方法会将引用的对象注册为要返回的实用程序实例,而工厂方法将调用引用的对象并将结果存储为要返回的实用程序实例。
工厂实例
例如,如果您有一个如下定义的实用程序类;
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 混淆
这些都不能与 IFactory 混淆,IFactory 确实提供了一些东西,可以在每次需要时为您提供一个新实例,但 API 略有不同。看 有关这些内容的更多信息,请参阅本文档.