In Yii2, it is possible to define interfaces in the constructor parameters, and the necessary implementations will be included there, defined via Yii :: $ container-> set ();

For example, in the authorization controller, I do this

public function __construct($id, $module, IAuthModelBuilder $modelBuilder, IAuthorizator $auth){} 

All implementations are defined in a separate file and loaded directly into the config.

Now I need, depending on what is passed in the request, to change the implementation of the IAuthorizator

In the config, you can set the 'on beforeRequest' event, but it is still not clear what controller and action is.

beforeAction is also not suitable, because in this place the controller has already been created and transferred to it.

How to be? Where is the place where the controller has not been created yet, but the url is already recognized?

  • Create a class that can return both implementations and inject it. - vp_arth
  • @vp_arth It turns out double injection) I would like to get by with one level) - Skywave
  • Here it is best to transfer the factory and not a specific object. - Lesha Marchenkovsky

1 answer 1

Why don't you want to resolve the dependency through a separate method?

 // remove dependency from here public function __construct($id, $module, IAuthModelBuilder $modelBuilder){} public function actionAuthorize() { $auth = $this->getAuthorizator(); // another part of code; } private function getAuthorizator() : IAuthorizator { if (Yii::$app->getRequest()->getQuery()) { // return needed auth module here } } 

Read about the different ways to add dependency here . Implementation is not limited to the designer.

  • I thought in this chip DI that the controller does not have to change, and the behavior changes. - Skywave
  • In addition to the resolver in the form of the getAuthorizator () function, you will not have to change anything. You can, of course, try to bring it to a higher level, but is it necessary? Look at the callable implementation, maybe it’s just what you need yiiframework.com/doc-2.0/… Then you’ll get rid of the logic implementation in the controller and ask $ container-> get ('auth') - Zhukov Roman
  • I have done the dependency handler in beforeRequest, also outside the controller, but the trouble is that the url hasn't been parsed yet. I looked at the link, it is possible to inject the dependency right into the action, and call the handler in the global beforeAction - the controller and everything else is already clear there. Thanks for the help! - Skywave