PhalconPHP DI:初始化器

时间:2014-10-10 07:47:42

标签: php dependency-injection phalcon

我目前正在测试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

1 个答案:

答案 0 :(得分:1)

  

依赖注入引用有一个例子,如果一个类实现Phalcon\DI\InjectionAwareInterface,它会自动将DI注入该类。

这并不完全正确,这意味着当服务被解析时DI会自动注入,因为它实现了这个接口,因为该类实现了一些接口,所以DI并不神奇地出现在那里。

  

如果一个类有例如Aranea\Db\DbAdapterAware,它应该自动在该类中注入DbAdapter。

如果您的类扩展Phalcon\DI\Injectable(或以与InjectionAwareInterface相同的方式实现Phalcon\DI\Injectable),那就是它的工作方式(不是技术上的)。在Injectable内部有一个__get魔法,如果服务存在,它将从DI返回服务。换句话说,东西只能在DI中注入,其他类在那里查找服务。

要注入您自己的服务,您可以将其在配置中传递给DI,也可以扩展DIFactoryDefault。两者之间的区别在于FactoryDefault已预先配置了有用的服务,但您可能不需要这些服务。

  

我假设在DI初始化期间但是在第一次调用时没有初始化方法,所以get *听起来更合适吗?

是的,有一个Phalcon\DI\Service对象代表服务并在第一次调用时解决(如果它是共享服务)或每次都解决(如果不是)。您通常希望共享所有服务,否则这通常会成为瓶颈,例如,在解析非共享数据库适配器时,每次调用它时都会建立连接...

PS:请注意,要使用DbAdapter工作,您可以执行以下操作:

  1. 添加适配器getter并返回DI::getDefault()->getShared('db');
  2. 在创建类时扩展Phalcon\DI\Injectable并设置DI,以便查找服务。
  3. 每次需要适配器时,只需从DI中获取,如第一个选项中所示。