<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>LoSoBlog</title>
	<atom:link href="http://losohome.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://losohome.wordpress.com</link>
	<description></description>
	<lastBuildDate>Thu, 08 Sep 2011 15:23:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='losohome.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>LoSoBlog</title>
		<link>http://losohome.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://losohome.wordpress.com/osd.xml" title="LoSoBlog" />
	<atom:link rel='hub' href='http://losohome.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Parameter injection with @Value</title>
		<link>http://losohome.wordpress.com/2010/01/24/parameter-injection-with-value/</link>
		<comments>http://losohome.wordpress.com/2010/01/24/parameter-injection-with-value/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 10:50:46 +0000</pubDate>
		<dc:creator>Loïc Frering</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[annotations]]></category>
		<category><![CDATA[dependencyinjection]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://losohome.wordpress.com/?p=46</guid>
		<description><![CDATA[I recently added support to @Value annotation to the ServiceContainerAnnotationsLoader. See my previous post for detailed information about this loader for Symfony Dependency Injection component. Inspired by Spring Framework 3.0 new equivalent annotation, it allows to inject parameter values defined in your service container with a simple annotation in your services. Check the updated code [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=losohome.wordpress.com&amp;blog=11535183&amp;post=46&amp;subd=losohome&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently added support to @Value annotation to the ServiceContainerAnnotationsLoader. See my <a href="http://losohome.wordpress.com/2010/01/20/using-annotations-with-symfony-dependency-injection-component/" title="Using annotations with Symfony Dependency Injection Component">previous post</a> for detailed information about this loader for Symfony Dependency Injection component.</p>
<p>Inspired by Spring Framework 3.0 new equivalent annotation, it allows to inject parameter values defined in your service container with a simple annotation in your services. Check the updated code on my <a href="http://bitbucket.org/loic_frering/losolib/src/tip/library/LoSo/Symfony/Components/">Bitbucket</a>.</p>
<p>If you use @Value without description, the parameter identifier will be automatically determined. You can also explicitly define the parameter identifier: @Value %mail.transport%.</p>
<p><pre class="brush: plain;">
parameters:
    foo: bar
    mailer.username: foo
    mailer.password: bar
</pre></p>
<p><pre class="brush: php;">
/** 
 * @Service 
 */ 
class Default_Service_TestService 
{ 
    /** 
     * @Value
     */ 
    protected $_foo; 
  
    public function setFoo($foo) 
    { 
        $this-&gt;_foo = $foo; 
        return $this; 
    }

    protected $_username;

    /*
     * @Value %mailer.username%
     */
    public function setUsername($username)
    {
        $this-&gt;_username = $username;
        return $this;
    }

    // ....
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/losohome.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/losohome.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/losohome.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/losohome.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/losohome.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/losohome.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/losohome.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/losohome.wordpress.com/46/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=losohome.wordpress.com&amp;blog=11535183&amp;post=46&amp;subd=losohome&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://losohome.wordpress.com/2010/01/24/parameter-injection-with-value/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c536079d77146d0902bdef0fcd1cbc25?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Loïc Frering</media:title>
		</media:content>
	</item>
		<item>
		<title>Integrating Symfony Dependency Injection Service Container with Zend Framework</title>
		<link>http://losohome.wordpress.com/2010/01/22/integrating-symfony-dependency-injection-service-container-with-zend-framework/</link>
		<comments>http://losohome.wordpress.com/2010/01/22/integrating-symfony-dependency-injection-service-container-with-zend-framework/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 01:37:27 +0000</pubDate>
		<dc:creator>Loïc Frering</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[annotations]]></category>
		<category><![CDATA[dependencyinjection]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[zendframework]]></category>

		<guid isPermaLink="false">http://losohome.wordpress.com/?p=21</guid>
		<description><![CDATA[Now we can use annotations to load our services definitions into the Symfony Dependency Injection container. For the second part of this series on Dependency Injection, we are going to see an elegant way to integrate the Symfony service container with your Zend Framework application. During my researches, I found two blog posts that guided [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=losohome.wordpress.com&amp;blog=11535183&amp;post=21&amp;subd=losohome&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Now we can <a href="http://losohome.wordpress.com/2010/01/20/using-annotations-with-symfony-dependency-injection-component/" title="Using annotations with Symfony Dependency Injection Component">use annotations</a> to load our services definitions into the Symfony Dependency Injection container.</p>
<p>For the second part of this series on Dependency Injection, we are going to see an elegant way to integrate the Symfony service container with your Zend Framework application.</p>
<p><span id="more-21"></span></p>
<p>During my researches, I found two blog posts that guided me for this integration:</p>
<ul>
<li>
The <a href="http://www.whitewashing.de/blog/articles/118" title="Using Symfony Dependency Injection with Zend_Application">first one</a> is from Benjamin Eberlei and shows how to replace the Zend_Application default bootstrap container with the Symfony Service Container.</li>
<li>The <a href="http://blog.starreveld.com/2009/11/using-symfony-di-container-with.html" title="Using Symfony dependency injection Container with Zend_Bootstrap">second one</a> from Dolf Starreveld shows the same as Benjamin but with a more advanced integration by subclassing Zend_Application_Bootstrap_BootstrapAbstract class.</li>
</ul>
<p>In the following post I will expose how to integrate the Symfony Dependency Injection container into Zend_Application bootstrap with a simple implementation of a ServiceContainerFactory. I will then expose how to inject your defined services into your controller with an action helper and with a simple @Inject annotation!</p>
<h1>Replace the default boostrap container with Symfony&#8217;s Service Container</h1>
<p>Since Zend Framework 1.8 bootstrapping applications is much more easier thanks to <a href="http://framework.zend.com/manual/en/zend.application.html" title="Zend_Application">Zend_Application</a>. It facilitates application bootstrapping and provides reusable resources to easily configure and initiate various components you will use such as Zend_Layout, Zend_Translate, Zend_Navigation or Zend_Db.</p>
<p>To be accessible throughout your application, the resources objects are registered in a container also called the resource registry. And as Matthew Weier O&#8217;Phinney (ZF&#8217;s project lead) said in Benjamin&#8217;s post comments, this explicit design was made to use a Dependency Injection container instead of the default Zend_Registry instance. So we are gonna replace this default registry with the full featured Symfony&#8217;s Dependency Injection container.</p>
<p>I wrote a class named LoSo_Zend_Application_Bootstrap_Bootstrap which extends the default Zend_Application_Bootstrap_Bootstrap class :</p>
<p><pre class="brush: php;">
/**
 * Description of LoSo_Zend_Application_Bootstrap_Bootstrap
 *
 * @author Loïc Frering &lt;loic.frering@gmail.com&gt;
 */
class LoSo_Zend_Application_Bootstrap_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    public function getContainer()
    {
        $options = $this-&gt;getOption('bootstrap');

        if(null === $this-&gt;_container &amp;&amp; $options['container']['type'] == 'symfony') {
            $autoloader = Zend_Loader_Autoloader::getInstance();
            $autoloader-&gt;pushAutoloader(array('LoSo_Symfony_Components_Autoloader', 'autoload'));
            $container = LoSo_Symfony_Components_ServiceContainerFactory::getContainer($options['container']);
            $this-&gt;_container = $container;
            Zend_Controller_Action_HelperBroker::addHelper(new LoSo_Zend_Controller_Action_Helper_ServiceContainer());
        }
        return parent::getContainer();
    }
}
</pre></p>
<p>It overrides the getContainer method where I instantiate and return a Symfony Service Container if the option bootstrap.container.type value is set to symfony in your configs/application.ini file. Three main operations are done here:</p>
<ul>
<li>Registering the autoloader for loading Symfony Components classes</li>
<li>Getting a Service Container instance from a factory</li>
<li>Adding a helper for dependency injection to the action helper broker.</li>
</ul>
<p>The <a href="http://bitbucket.org/loic_frering/losolib/src/925e533444d2/library/LoSo/Symfony/Components/Autoloader.php" title="LoSo_Symfony_Components_Autoloader">LoSo_Symfony_Components_Autoloader</a> is a simple class I developed to easily autoload the classes of the two Symfony Components necessary here: Dependency Injection and YAML (for defining services into YAML files). I will not describe it here, see the code for implementation details.</p>
<h1>The Service Container Factory</h1>
<p>LoSo_Symfony_Components_ServiceContainerFactory class purpose is to instantiate and configure the Symfony Service Container. Just pass an array of options to getContainer method to get an instance:</p>
<p><pre class="brush: php;">
class LoSo_Symfony_Components_ServiceContainerFactory
{
    protected static $_container;

    public static function getContainer(array $options)
    {
        self::$_container = new sfServiceContainerBuilder();
        foreach($options['configFiles'] as $file) {
            self::_loadConfigFile($file);
        }

        return self::$_container;
    }

    protected static function _loadConfigFile($file)
    {
        $suffix = strtolower(pathinfo($file, PATHINFO_EXTENSION));

        switch ($suffix) {
            case 'xml':
                $loader = new sfServiceContainerLoaderFileXml(self::$_container);
                break;

            case 'yml':
                $loader = new sfServiceContainerLoaderFileYaml(self::$_container);
                break;

            case 'ini':
                $loader = new sfServiceContainerLoaderFileIni(self::$_container);
                break;

            default:
                throw new Atos_Symfony_Exception(&quot;Invalid configuration file provided; unknown config type '$suffix'&quot;);
        }
        $loader-&gt;load($file);
    }
}
</pre></p>
<p>As you can see in the extended Bootstrap class, the bootstrap.container.* options retrieved from application.ini are passed to the factory. You can specify definition files to load thanks to the configFiles array option:</p>
<p><pre class="brush: plain;">
bootstrap.path = APPLICATION_PATH &quot;/Bootstrap.php&quot;
bootstrap.class = &quot;Bootstrap&quot;
bootstrap.container.type = &quot;symfony&quot;
bootstrap.container.configFiles[] = APPLICATION_PATH &quot;/configs/services.yml&quot;
</pre></p>
<p>Then the factory loads to the Service Container each configuration file by instantiating the correct loader according to the file extension.</p>
<h1>Dependency Injection action helper</h1>
<p>We have now integrated Symfony service container with Zend_Application and loaded configuration files easily defined in our application.ini. The last operation done in the extended getContainer method was to register a service container action helper. Let&#8217;s see now how to retrieve services from our controllers with this action helper.</p>
<p>The direct function allows to retrieve a service or a parameter by his identifier while the getContainer method simply returns the Symfony service container instance:</p>
<p><pre class="brush: php;">
class LoSo_Zend_Controller_Action_Helper_ServiceContainer extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @var sfServiceContainer
     */
    protected $_container;

    public function __construct()
    {
        $this-&gt;_container = $this-&gt;getActionController()-&gt;getInvokeArg('bootstrap')-&gt;getContainer();
    }

    public function direct($name)
    {
        if($this-&gt;_container-&gt;hasService($name)) {
            return $this-&gt;_container-&gt;getService($name);
        }
        else if($this-&gt;_container-&gt;hasParameter($name)) {
            return $this-&gt;_container-&gt;getParameter($name);
        }
        return null;
    }

    public function  getContainer() {
        return $this-&gt;_container;
    }
}
</pre></p>
<p>Here are some examples on how you can use this helper in your controllers:</p>
<p><pre class="brush: php;">
class MyController extends Zend_Controller_Action
{
    protected $_testService;

    public function init()
    {
        $this-&gt;_testService = $this-&gt;_helper-&gt;serviceContainer('testService');
    }

    public function indexAction()
    {
        $serviceContainer = $this-&gt;_helper-&gt;serviceContainer-&gt;getContainer();
        $myService = $serviceContainer-&gt;getService('myService');
        $myService = $serviceContainer-&gt;myService;
        $param = $serviceContainer-&gt;getParameter('param');
        // ....
    }
}
</pre></p>
<h1>Depency Injection with annotations within our controllers</h1>
<p>To ease and automate dependency injection in our controllers, we are going to use annotations to declare the services we want to be automatically injected. To achieve this task, we can think about declaring our controller classes in the service container by loading them with the ServiceContainerAnnotationsLoader I described in my <a href="http://losohome.wordpress.com/2010/01/20/using-annotations-with-symfony-dependency-injection-component/" title="Using annotations with Symfony Dependency Injection Component">previous post</a>.</p>
<p>But we are not directly in charge of the controller instantiation, that&#8217;s the <a href="http://framework.zend.com/manual/en/zend.controller.dispatcher.html" title="Zend_Controller_Dispatcher">dispatcher</a>&#8216;s main mission. In a first approach I did not wanted to extend the standard dispatcher to let him manage the controllers lifecycle. Instead I decided to use introspection on the controller instance to inject the annotated dependencies. The best way to achieve this is in the preDispatch hook of an action helper because at this stade: the controller has been instantiated by the standard dispatcher and you can retrieve it via the getActionController method of Zend_Controller_Action_Helper_Abstract class.</p>
<p>Helper class? Hey we&#8217;ve just developed one for our service container! So here&#8217;s the complete implementation I made of my LoSo_Controller_Action_Helper_ServiceContainer:</p>
<p><pre class="brush: php;">
class LoSo_Zend_Controller_Action_Helper_ServiceContainer extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @var sfServiceContainer
     */
    protected $_container;

    public function __construct()
    {
        $this-&gt;_container = $this-&gt;getActionController()-&gt;getInvokeArg('bootstrap')-&gt;getContainer();
    }

    public function preDispatch()
    {
        $actionController = $this-&gt;getActionController();

        $r = new Zend_Reflection_Class($actionController);
        $properties = $r-&gt;getProperties();

        foreach($properties as $property) {
            if($property-&gt;getDeclaringClass()-&gt;getName() == get_class($actionController)) {
                if($property-&gt;getDocComment()-&gt;hasTag('Inject')) {
                    $injectTag = $property-&gt;getDocComment()-&gt;getTag('Inject');
                    $serviceName = $injectTag-&gt;getDescription();
                    if(empty($serviceName)) {
                        $serviceName = $this-&gt;_formatServiceName($property-&gt;getName());
                    }
                    if($this-&gt;_container-&gt;hasService($serviceName)) {
                        $property-&gt;setAccessible(true);
                        $property-&gt;setValue($actionController, $this-&gt;_container-&gt;getService($serviceName));
                    }
                }
            }
        }
        
    }

    protected function _formatServiceName($serviceName)
    {
        if(strpos($serviceName, '_') === 0) {
            $serviceName = substr($serviceName, 1);
        }
        return $serviceName;
    }

    public function direct($name)
    {
        if($this-&gt;_container-&gt;hasService($name)) {
            return $this-&gt;_container-&gt;getService($name);
        }
        else if($this-&gt;_container-&gt;hasParameter($name)) {
            return $this-&gt;_container-&gt;getParameter($name);
        }
        return null;
    }

    public function  getContainer() {
        return $this-&gt;_container;
    }
}
</pre></p>
<p>Here&#8217;s what the preDispatch method do:</p>
<ul>
<li>Introspect the action controller class</li>
<li>For each property of the class, if the property is tagged @Inject:</li>
<ul>
<li>Determine which service identifier we want to inject:</li>
<ul>
<li>If a service name is explicitly defined in the @Inject description (eg @Inject myService), use this name as identifier</li>
<li>If not, use property name (with no _ if it begins with) as identifier</li>
</ul>
<li>Check if the service is declared in the container</li>
<li>Then inject the service instance into the property</li>
</ul>
</ul>
<p>Here we are, we can now easily inject services into our controllers:</p>
<p><pre class="brush: php;">
class MyController extends Zend_Controller_Action
{
    /**
     * @Inject
     */
    private $_testService;

    public function indexAction()
    {
        // ....
    }
}
</pre></p>
<p>The whole code base and examples are available on my <a href="http://bitbucket.org/loic_frering/losolib/wiki/Home" title="LoSoLib">Bitbucket</a>.</p>
<h1>Coming soon</h1>
<p>My next post will describe how to automatically load your services classes into the container with the annotation loader. You will then just have to tag @Service the classes you want to be managed by the service container with no overhead XML or YAML configuration file.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/losohome.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/losohome.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/losohome.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/losohome.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/losohome.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/losohome.wordpress.com/21/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/losohome.wordpress.com/21/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/losohome.wordpress.com/21/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=losohome.wordpress.com&amp;blog=11535183&amp;post=21&amp;subd=losohome&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://losohome.wordpress.com/2010/01/22/integrating-symfony-dependency-injection-service-container-with-zend-framework/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c536079d77146d0902bdef0fcd1cbc25?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Loïc Frering</media:title>
		</media:content>
	</item>
		<item>
		<title>Using annotations with Symfony Dependency Injection Component</title>
		<link>http://losohome.wordpress.com/2010/01/20/using-annotations-with-symfony-dependency-injection-component/</link>
		<comments>http://losohome.wordpress.com/2010/01/20/using-annotations-with-symfony-dependency-injection-component/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 00:05:13 +0000</pubDate>
		<dc:creator>Loïc Frering</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[annotations]]></category>
		<category><![CDATA[dependencyinjection]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[zendframework]]></category>

		<guid isPermaLink="false">http://losohome.wordpress.com/?p=3</guid>
		<description><![CDATA[Having worked a lot with Spring Framework for Java EE projects, I was looking for an Inversion of Control container for managing Dependency Injection in PHP in my Zend Framework applications instead of factories. I closely followed Fabien Potencier&#8217;s (Symfony&#8217;s project lead) series on Dependency Injection in spring (season) 2009 and I recently took the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=losohome.wordpress.com&amp;blog=11535183&amp;post=3&amp;subd=losohome&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Having worked a lot with <a href="http://www.springsource.org/" title="Spring Framework">Spring Framework</a> for Java EE projects, I was looking for an Inversion of Control container for managing Dependency Injection in PHP in my <a href="http://framework.zend.com" title="Zend Framework">Zend Framework</a> applications instead of factories. I closely followed Fabien Potencier&#8217;s (Symfony&#8217;s project lead) <a href="http://fabien.potencier.org/article/11/what-is-dependency-injection" title="Fabien Potencier's blog">series on Dependency Injection</a> in spring (season) 2009 and I recently took the time to begin testing the <a href="http://components.symfony-project.org/dependency-injection/" title="Symfony Dependency Injection">Dependency Injection container from Symfony Components</a>. Quite satisfied with it I decided to integrate it with Zend Framework and to add the possibility to use docblock annotations to describe services with a new loader for the component.</p>
<p><span id="more-3"></span></p>
<p>I will not cover here the benefits of using a Dependency Injection container in your applications, refer to all the resources you can find on the web. As well, I will not debate about the pertinence to use a DI container with dynamic languages such as PHP nor Ruby.</p>
<p>So let&#8217;s start with the annotation loader. I developed a class called LoSo_Symfony_Components_ServiceContainerLoaderAnnotations which extends sfServiceContainerLoader. I use Zend_Reflection for the introspection of docblocks and his ability to retrieve annotation tags. The class is available on my <a href="http://github.com/loicfrering/losolib/tree/master/library/LoSo/Symfony/Components/DependencyInjection/Loader/" title="GitHub">GitHub</a>.</p>
<p>Let&#8217;s see an example of an annotation described service:</p>
<p><pre class="brush: php;">
/**
 * Description of Default_Service_TestService
 *
 * @author Loïc Frering &lt;loic.frering@gmail.com&gt;
 * @Service
 */
class Default_Service_TestService
{
    /**
     * @var Default_Service_TestService2
     */
    protected $_testService2;

    /**
     * @param Default_Service_TestService2 $testService2
     * @return Default_Service_TestService
     * @Inject
     */
    public function setTestService2($testService2)
    {
        $this-&gt;_testService2 = $testService2;
        return $this;
    }

    public function test()
    {
        return 'Test method from TestService';
    }

    public function test2()
    {
        return $this-&gt;_testService2-&gt;test2() . ' called from testService';
    }
}
</pre></p>
<h1>@Service annotation</h1>
<p>The @Service annotation register the class as a service managed by the DI Container. If no string follows the @Service annotation, the class name will be used to determine the service identifier:</p>
<ul>
<li>Default_Service_TestService will be identified as testService</li>
<li>MyService will be identified as myService</li>
</ul>
<p>You can also explicitly specify the service identifier:</p>
<p><pre class="brush: php;">
/**
 * @Service myService
 */
</pre></p>
<h1>@Inject annotation</h1>
<p>The @Inject annotation specify a dependence that need to be injected by the container. You can use the annotations in three different ways.</p>
<h2>Constructor injection</h2>
<p>@Inject annotated constructor arguments will be introspected and declared in the Service Container for injection. The argument name will be used to determine the service id to inject.</p>
<p><pre class="brush: php;">
/**
 * @Service
 */
class Default_Service_TestService
{
    /**
     * @var Default_Service_MyService
     */
    protected $_myService;

    /**
     * @Inject
     */
    public function __construct($myService)
    {
        $this-&gt;_myService = $myService;
    }

    // ....
}
</pre></p>
<h2>Property injection</h2>
<p>When the loader encounters a properties with the @Inject annotation, a method call will be declared in the service container to make the injection. A _testService or testService property will register a method call to setTestService with the testService as service identifier for injection.</p>
<p><pre class="brush: php;">
/**
 * @Service
 */
class Default_Service_TestService
{
    /**
     * @var Default_Service_MyService
     * @Inject
     */
    protected $_myService;

    public function setMyService($myService)
    {
        $this-&gt;_myService = $myService;
    }

    // ....
}
</pre></p>
<p>You can also explicitly specify the service identifier:</p>
<p><pre class="brush: php;">
/**
 * @Inject myService
 */
</pre></p>
<h2>Setter injection</h2>
<p>A setter method with @Inject annotation will also register a method call for a service injection. The service identifier to inject, if not explicitly defined with the annotation, will be determined with the method name : testService service will be injected in the setTestService method.</p>
<p><pre class="brush: php;">
/**
 * @Service
 */
class Default_Service_TestService
{
    /**
     * @var Default_Service_MyService
     */
    protected $_myService;

    /**
     * @Inject
     */
    public function setMyService($myService)
    {
        $this-&gt;_myService = $myService;
    }

    // ....
}
</pre></p>
<h1>Using the loader</h1>
<p>Using the loader is as simple as using XML or YAML loaders. Just pass to the loader constructor a path to a directory to be scanned by the loader:</p>
<p><pre class="brush: php;">
$container = new sfServiceContainerBuilder();
$loader LoSo_Symfony_Components_ServiceContainerLoaderAnnotations($container);
$loader-&gt;load($path);
</pre></p>
<h1>The Need for Speed</h1>
<p>As you might have wondered, using annotations introspection on each request is not very efficient. Not a problem: have a look at Symfony Dependency Injection component documentation and paticularly at the chapter named <a href="http://components.symfony-project.org/dependency-injection/trunk/book/06-Speed" title="The Need for Speed">The Need for Speed</a>.</p>
<p>Did you read it ? So you just have to use the PHP dumper to generate the plain optimized PHP code for your Service Container with the definition corresponding to what you have declared with your annotations.</p>
<p><pre class="brush: php;">
$dumper = new sfServiceContainerDumperPhp($container);
file_put_contents($file, $dumper-&gt;dump(array('class' =&gt; 'MyContainer'));
</pre></p>
<p>Then stock the generated file when it does not exist on the first request and use the generated class on the following request.</p>
<h1>Coming soon</h1>
<p>Next post will be about elegant integration of Symfony Dependency Injection component with Zend Framework. You will be able to inject your services in your controllers with a simple @Inject annotation!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/losohome.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/losohome.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/losohome.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/losohome.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/losohome.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/losohome.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/losohome.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/losohome.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=losohome.wordpress.com&amp;blog=11535183&amp;post=3&amp;subd=losohome&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://losohome.wordpress.com/2010/01/20/using-annotations-with-symfony-dependency-injection-component/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c536079d77146d0902bdef0fcd1cbc25?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Loïc Frering</media:title>
		</media:content>
	</item>
	</channel>
</rss>
