Dependency injection basics

Hello,

Can anyone explain me DI basics please? I understand what it is, but I don’t really know now, how to use DI container in practice. For example, I have 2 functions in the same controller:




public function actionIndex()

{

    $productsModel = new Products();

    $productsFormModel = new ProductsForm();

    $informationFormModel = new InformationForm();


    ....

}


public function actionInformation()

{

    $productsModel = new Products();

    $productsFormModel = new ProductsForm();

    $informationFormModel = new InformationForm();


    ....

}



So my two questions is:

  1. As you see above, I use same models in these functions. It is good idea to initialized them into "public function init() {}" and then use them in all class globally or this is bad idea?

  2. I think it should be better if these models would be injected into this controller, right? How to do it correctly?

I was created file DI.php, which I included into entry script. File content was:




<?php


    \Yii::$container->set('products_model', 'app\models\Products');

    \Yii::$container->set('products_form', 'app\models\ProductsForm');

    \Yii::$container->set('information_form', 'app\models\InformationForm');


?>



So then I was able to get class app\models\Products instance globally (in every controller, view or model):




$instance_products = \Yii::$container->get('products_model');

$instance_products_form = \Yii::$container->get('products_form');

$instance_information_form = \Yii::$container->get('information_form');



But this is bad idea, right?

Please, answer someone my two questions. :)

Thanks!

Please, help! :unsure:

1.Dependency injection would be a massive overkill when all you need is a new model instance, without any configuration, additional dependencies etc. It’s also unlikely that you will need to replace Products model with another implementation at runtime.

  1. Having similar code snippets in multiple actions doesn’t necessarily mean code duplication but it’s hard to tell without seeing the whole code. If it’s a real code duplication there are other options for refactoring: action classes, widgets, controller behaviors, application components…, depending on the actual problem.

Thanks for answer!

So in what situation it is good to use \Yii::$container->set() and \Yii::$container->get() ?

And this is bad idea:




    private $productsModel;

    private $productsFormModel;

    private $informationFormModel;


    public function init()

    {

        $this->productsModel = new Products();

        $this->productsFormModel = new ProductsForm($this->productsModel);

        $this->informationFormModel = new InformationForm();

    }



?

I mentioned a few use cases for dependency injection above:

  • the dependency requires configuration and/or additional dependencies

  • you want to be able to replace it with a different implementation without changing controller code

It isn’t a bad idea but it might be unnecessary. The question is: Will any change in implementation of actionIndex make it necessary to change the implementation of actionInformation too (or vice versa)? If not, just leave them as they are. There’s nothing wrong with with creating new model instances anywhere you need them.