How to use DI Container the elegant way ?

In the guide we can see this example: http://www.yiiframework.com/doc-2.0/yii-di-container.html

In the example, dependency declaration and object creation are happening at the same place in code. I am trying to move the declaration to one spot. I want to declare all dependencies in one place, and then just use them throughout my code. I have some problem, and I do not know why it is happening.

For example. I have interface SomeServiceInterface, and implementation SomeService. I would like to declare the dependency in one place in application like this:


$container->set('common\components\SomeServiceInterface', [

    'class' => 'common\components\SomeService',

]);

And then, when I need the object of SomeService ( actually I need the implementation of that interface ), I would like to do this




$container = new Container;

$someService = $container->get('common\components\SomeServiceInterface');



It seems that this is possible only if you declare and use the dependencies at the same spot in code, like in the guide.

What I have tried, is that I create component that is bootstraped at the application start, and inside that componenet I have declared all my dependencies. Then in my controller, I have tried to use one of those, but I am getting an error.

Code example.

Component:


class ContainerConfigurator extends Component

{

    /**

     * interface => implementation

     * 

     * @var [type]

     */

    private $_config = [

        'common\components\SomeServiceInterface' => 'common\components\SomeService'

    ];


    public function init() 

    {

        $container = new Container;


        foreach ($this->_config as $interface => $implementation) {

            $container->set($interface, $implementation);

        }

    }

}

Bootstraped:


'bootstrap' => ['common\components\ContainerConfigurator'],

Used:


use yii\di\Container;


$container = new Container;

$service = $container->get('common\components\SomeServiceInterface');

Error:


Not instantiable – yii\di\NotInstantiableException


Can not instantiate common\components\SomeService.

Is this even possible, or am I doing something wrong ?

1 Like

You’re doing something wrong. You’re setting dependencies to one instance of container but then creating another instance and trying to get dependencies from it. Second one is just created so contains nothing.

You need to keep a reference to your container somewhere and Yii did that for you already. There’s Yii::$container you can use for the purpose. But there’s one thing. You actually should not directly use container except when defining dependencies else its purpose won’t be fulfilled so set dependencies in Yii::$container and then get em via type-wiring in constructors.

1 Like

That makes sense. Thank you very much, you are very helpful as always.

I touch a bit the question here

http://www.yiiframework.com/forum/index.php/topic/75313-yii2-dependency-injection-with-activerecord/page__view__findpost__p__311865