我目前正在测试phalcon php的项目,我正在寻找一种基于实现的接口自动注入某些类的方法。
The Dependency Injection reference有一个例子,如果一个类实现Phalcon\DI\InjectionAwareInterface
,它会自动将DI注入该类。
我想做的是类似的。如果一个类具有例如Aranea\Db\DbAdapterAware
,它应该自动在该类中注入DbAdapter。我正在寻找类似于Zend Framework 2所做的事情(https://juriansluiman.nl/article/121/interface-injection-with-initializers-in-zend-servicemanager),在DI配置期间你可以指定这样的初始化器:
'initializers' => array(
'logger' => function($service, $sm) {
if ($service instanceof LoggerAwareInterface) {
$logger = $sm->get('logger');
$service->setLogger($logger);
}
}
),
如果在PhalconPHP中无法自动执行此操作,我会考虑覆盖FactoryDefault
类并自行实现。注入这种逻辑的正确位置是什么?在get *方法中,或者更确切地说在set *方法中?我假设在DI初始化期间但是在第一次调用时没有初始化方法,所以get *听起来更合适吗?
感谢您的建议,
的Jeroen
答案 0 :(得分:1)
依赖注入引用有一个例子,如果一个类实现
Phalcon\DI\InjectionAwareInterface
,它会自动将DI注入该类。
这并不完全正确,这意味着当服务被解析时DI会自动注入,因为它实现了这个接口,因为该类实现了一些接口,所以DI并不神奇地出现在那里。
如果一个类有例如
Aranea\Db\DbAdapterAware
,它应该自动在该类中注入DbAdapter。
如果您的类扩展Phalcon\DI\Injectable
(或以与InjectionAwareInterface
相同的方式实现Phalcon\DI\Injectable
),那就是它的工作方式(不是技术上的)。在Injectable
内部有一个__get
魔法,如果服务存在,它将从DI返回服务。换句话说,东西只能在DI中注入,其他类在那里查找服务。
要注入您自己的服务,您可以将其在配置中传递给DI,也可以扩展DI
或FactoryDefault
。两者之间的区别在于FactoryDefault
已预先配置了有用的服务,但您可能不需要这些服务。
我假设在DI初始化期间但是在第一次调用时没有初始化方法,所以get *听起来更合适吗?
是的,有一个Phalcon\DI\Service
对象代表服务并在第一次调用时解决(如果它是共享服务)或每次都解决(如果不是)。您通常希望共享所有服务,否则这通常会成为瓶颈,例如,在解析非共享数据库适配器时,每次调用它时都会建立连接...
PS:请注意,要使用DbAdapter
工作,您可以执行以下操作:
DI::getDefault()->getShared('db')
; Phalcon\DI\Injectable
并设置DI,以便查找服务。