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.
3. Extends CWebApplication
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
into
5. Now its time for configuration!
The last step is set the configuration elements we need
Now if everything is set up correctly you can access your dic in these ways:
Hope you enjoy this tutorial!!! Feel free to ask for help!!!
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!!!