Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.1] Make Container PSR-11 compatible, support different PSR-11 DI containers #14112

Closed
3 tasks
SamMousa opened this issue May 4, 2017 · 2 comments
Closed
3 tasks

Comments

@SamMousa
Copy link
Contributor

SamMousa commented May 4, 2017

TODO:

  • Make container PSR-11 compatible.
  • Introduce aliasing.
  • Make it possible to use another PSR-11 compatible container.

Original issue:

This is related to my open PR(#14107) regarding PSR-11 compatibility, it is not the same however.
My PR is about making the Yii DI container usable in libraries that need a PSR-11 container.
This is to be a discussion about supporting other DI containers for usage within Yii.

Yii's DI container does some things that are out of the scope of PSR-11.
These are:

  1. Allowing to not only resolve dependencies for objects but also for callables.
  2. Allow configuring of objects via ->get(..., ..., ...).
  3. Allow passing constructor arguments to the object that must be returned.

Note that (1) and (2) can be refactored to wrap any PSR-11 container instead of being part of a container itself. (3) however is a problem. Since $container->get() will return the object there is no option to pass constructor arguments, for these cases we need to look for alternatives (which is why this is a 2.1 discussion).

There are currently 5 places in the Yii source code that pass constructor arguments to $container->get via Yii::createObject:

/base/Module.php[423]: $module = Yii::createObject($this->_modules[$id], [$id, $this]);
/base/Module.php[578]: $controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
/base/Module.php[638]: $controller = Yii::createObject($className, [$id, $this]);
/base/Controller.php[225]: return Yii::createObject($actionMap[$id], [$id, $this]);
/db/ActiveRecord.php[305]: return Yii::createObject(ActiveQuery::className(), [get_called_class()]);

These 5 calls instantiate (subclasses of) 3 classes:

yii\db\ActiveQuery
yii\base\Module
yii\base\Controller

In these specific cases the constructor arguments consist of public variables combined with a configuration array. The reason for these variables to be constructor arguments (they could also be configured via the configuration array) is that they are not optional but required.

I do not have a specific solution that I feel is best, but I think the above provides enough information to start a discussion.

tldr; if we want Yii to be able to use PSR-11 DI Containers we must:

  1. Decide how to handle constructor arguments outside DI
  2. Decide how to handle configuration outside DI
@lynicidn
Copy link
Contributor

lynicidn commented May 7, 2017

only more than 5 cases need to refactor, example look web\User component and how create url in loginRequired. If i can override user component in AccessFilter, but not override Url::to in loginRequired

@samdark samdark changed the title [2.1] Support different DI containers. [2.1] Make Container PSR-11 compatible, support different PSR-11 DI containers Sep 7, 2017
@samdark samdark modified the milestones: 2.1.0, 2.1.x Sep 7, 2017
@samdark samdark self-assigned this Sep 7, 2017
@klimov-paul
Copy link
Member

Issue merged into #15436

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants