Quantcast
Channel: Yii Framework Forum
Viewing all articles
Browse latest Browse all 18717

Yii Dependency Injection Container - Tutorial

$
0
0
Recenlty I was looking for a solution to integrate e dependency injection pattern into yii without modify the core. Today I just integrated a little class, well known and written by Fabien Potencier, Pimple.
I will explain here all the steps to add a simple dependency injection into your application that is also capable to retrieve Yii components and parameters.

1. Install Pimple
Here is the github page: Pimple, you can use composer or just download the single class and put that into your components (or whatever) directory.

2. Extend Pimple
Create a Class CContainer that extends Pimple and put it into components.
class CContainer extends \Pimple
{
    /**
     * Retrieve parameter/service.
     *
     * @param string $id id of parameter/service
     * to retrieve Yii specific param/service just use an id like "yii.core.paramName"
     *
     * @return mixed
     */
    public function get($id)
    {
        $element = null;
        if (strpos($id, 'yii.core.') !== false) {
            $id = str_replace('yii.core.', '', $id);
            $element = Yii::app()->{$id};
        } else {
            $element = $this[$id];
        }
        return $element;
    }

    /**
     * Set a new parameter/service
     * 
     * @param string $id    id of parameter/service
     * @param mixed  $value value or callable
     * 
     * @return void
     */
    public function set($id, $value)
    {
        $this[$id] = $value;
    }
}


3. Extends CWebApplication
class WebApplication extends CWebApplication
{
    /**
     * @var \Pimple dependency injection container
     */
    protected $_container = null;

    /**
     * Configure DiC.
     * 
     * @param array $config configuration parameters
     * it consists of two main parameters:
     * <pre>
     * array(
     *     'class' => 'CContainer',
     *     'services' => array(
     *         's1' => function($c) {
     *             return new S1();
     *         },
     *         's2' => function($c) {
     *             return new S2($c['s1');
     *         }
     *     ),
     * )
     * </pre>
     * @return void
     */
    public function setContainer(array $config)
    {
        $container = isset($config['class']) && !empty($config['class']) ? $config['class'] : 'CContainer';
        $services = isset($config['services']) && is_array($config['services']) && !empty($config['services'])
            ? $config['services']
            : array();
        $this->_container = new $container($services);
    }

    /**
     * Retrieve the DiC container.
     * 
     * @return CContainer
     */
    public function getContainer()
    {
        if ($this->_container === null) {
            $this->_container = new CContainer();
        }
        return $this->_container;
    }
}


4. Change the entry scripts
We need now to change the index.php, index-test.php and test/bootstrap.php to use our new WebApplication Class.
Just change this
Yii::createWebApplication($config)->run();

into
require_once('pathtoprotected/components/WebApplication.php');
Yii::createApplication('WebApplication', $config)->run();


5. Now its time for configuration!
The last step is set the configuration elements we need
// import your files here or use an auoloader (better)
Yii::import('application.components.container.Pimple', true);
Yii::import('application.components.container.CContainer', true);

return array(
    'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
    'name' => 'Yii Dependency Injection Integration',
    // application modules
    'modules' => array(
        // ...
    ),
    // application components
    'components' => array(
        // ...
    ),
    // dipendency injection configuration
    'container' => array(
        'class' => 'CContainer',
        'services' => array(
            // ... put here your services
        );
    ),
    // application-level parameters that can be accessed
    'params' => array(
        // ....
    ),
);


Now if everything is set up correctly you can access your dic in these ways:
// retrieve services1
$service_1 = Yii::app()->getContainer()->get('s1');
// retrieve yii urlManager
$url_manager = Yii::app()->getContainer()->get('yii.core.urlManager');


Hope you enjoy this tutorial!!! Feel free to ask for help!!! B)

Viewing all articles
Browse latest Browse all 18717

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>