基础开发与工具

Symfony服务容器介绍

2016-05-08  本文已影响834人  金宝财商

导读

这一系列的文章讲述了依赖注入概念和一个轻量级的PHP实现。

目录

正文

这个系列到目前为止,我们已经介绍了依赖注入的一般概念。前两篇介绍性的文章可以帮助我们更好的理解本篇文章及接下来的几篇文章中要讲述的依赖注入实现的内容。现在我们开始讨论Symfony 2服务容器的实现。

Symfony通过一个叫做sfServiceContainer的类来管理依赖注入容器。这是一个非常轻量的类,它实现了我们上一篇文章讨论过的基本功能。

Symfony服务容器可以作为独立的组件在其官方Subversion库来获取:点击
值得注意的是:这个组件仍然处于繁重的开发阶段,这意味着目前的实现有可能会发生改变。

按照Symfony的定义,一个服务可以是任意的被容器管理的对象。在上篇文章的Zend_Mail示例中,我们有两个服务:mailer服务和mail__transport服务:

class Container
{
  static protected $shared = array();

  protected $parameters = array();

  public function __construct(array $parameters = array())
  {
    $this->parameters = $parameters;
  }

  public function getMailTransport()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => $this->parameters['mailer.username'],
      'password' => $this->parameters['mailer.password'],
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }

  public function getMailer()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }

    $class = $this->parameters['mailer.class'];

    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());

    return self::$shared['mailer'] = $mailer;
  }
}

如果让Container类继承sfServiceContainer类,我们就可以稍微简化一下上面的代码:

class Container extends sfServiceContainer
{
  static protected $shared = array();

  protected function getMailTransportService()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => $this['mailer.username'],
      'password' => $this['mailer.password'],
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }

  protected function getMailerService()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }

    $class = $this['mailer.class'];

    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransportService());

    return self::$shared['mailer'] = $mailer;
  }
}

这还不够好,但是可以给我们提供一个更加清晰有力的接口。这是主要的修改:

服务标识符必须是唯一的,并且只能包含字母,数字,下划线和点号。点号可以用来定义容器内部的“命名空间”(例如mail.mailer和mail.transport)。

我们来看一下如何使用这一新的容器类:

require_once 'PATH/TO/sf/lib/sfServiceContainerAutoloader.php';
sfServiceContainerAutoloader::register();

$sc = new Container(array(
  'mailer.username' => 'foo',
  'mailer.password' => 'bar',
  'mailer.class'    => 'Zend_Mail',
));

$mailer = $sc->mailer;

由于Container类继承了sfServiceContainer类,我们可以享用一个更加清爽的接口:

即使你仍然需要自己做大量基础工作并且复制大量的代码,在有少量的服务需要管理时,使用sfServiceContainer类仍然是非常有帮助的。但是,当要管理的服务开始暴涨时,我们就需要更好的方式来描述这些服务了。

这也是为什么大多数时候你不会直接使用sfServiceContainer类。然而做为Symfony依赖注入容器实现的基石,依然值得投入一些时间来搞清楚它。

在下篇文章中我们要讨论一下sfServiceContainerBuilder类,它使得服务定义的过程变得简单。

原文链接


转载注明出处:
http://zengfeng.info/2016/05/symfony服务容器介绍

上一篇 下一篇

猜你喜欢

热点阅读