So... I can see $container
is a public static property of BaseYii
class.
How about add it to di
component of module? This make since?
(I can see something similar in @SamMousa issue)
...
'components' => [
'di' => function() {
return Yii::$container;
},
...
Will be get from controller in module
$container = Yii::$app->get('di'); // Dependency Injection Container
// or
$container = $this->module->get('di'); // Dependency Injection Container
$model = $container->get($this->modelNameOfContactForm); //do someting
let's discuss!
| Q | A
| ---------------- | ---
| Yii version | 2.0.13 dev
What's the benefit for doing so?
Any (some) examples in guide don't show how to $container will be create.
This is propose idea of multiple container's... For modules...
I don't think the container should be a component; but I do think the container should be application / module specific. And not a global static.
It means less global state outside the application object.
Container can not be an application component, application should be a part of container instead.
Agreed with @SamMousa. I was thinking about replacing ServiceLocator (SL) with Container (interface is pretty much the same) and making it module-specific (as SL is now) so we can always call $this->module->get()
instead of calling global objects.
In order to properly do that we should add support for container inheritance.
Container inheritance is a much discussed subject; angular 2 does it. I think it was discussed for psr container spec as well...
@silverfire application config might be in container but IMO a container instance should be in the application...
Container can not be an application component, application should be a part of container instead.
Cycle link? Application is a part of container; container is a application component (get from function)
I do think the container should be application / module specific. And not a global static.
It means less global state outside the application object.
...
'components' => [
'di' => function() {
return Yii::$container;
},
],
'modules' => [
'v1' => [
'class' => \api\v1\Module::class,
'components' => [
'di' => function() {
return \api\v1\Module::$container; //or some else
},
],
],
'v2' => [
'class' => \api\v2\Module::class,
'components' => [
'di' => function() {
return \api\v2\Module::$container; //or some else non-static
},
],
],
],
...
Will be get from controller in module
$container = Yii::$app->get('di'); // Dependency Injection Container
$model = $container->get($this->modelNameOfContactForm); //do someting in app di
// or
$container = $this->module->get('di'); // Dependency Injection Container
$model = $container->get($this->modelNameOfContactForm); //do someting in module di
this is will work?
No, now it is still static Yii::$container
, you just have an extra reference.
If the DI container creates the application object it must be created before the application. It could of course inject itself into the application.
````
class Application {
public function __construct(Container $container)
{
}
// Create container:
$container = new Container(['app' => ['class' => Application::class, ...]]);
// Run application via invoke.
$container->invoke(function(Application $app) {
$app->run();
});
// Run application via get:
$container->get(Application::class)->run();
````
Of course the container injected into the application does not have to be the same container. In fact, there is no reason to make the container a singleton; instead it would make sense to create a copy for "each" application instance, that way you only need to use the initial DI container to instantiate the application(s).
And at that point, if you create a DI container to instantiate one object, you're not doing DI, you're not even really doing SL, you're just doing a new
in a weird way.
Of course suppose your creating a ReactPHP type web server that uses multiple application objects to handle requests using DI for application creation makes sense...
@SamMousa how about still alive \Yii::$container
AND add more di container in bootstrap/config modules for work with module-dependence relations? This make sense for cross-modules communication, module-depend relations or any else like this?
It doesn't remove the global; which is the most important thing imo.
Decided not to change DI container much in 3.0. See roadmap.
Most helpful comment
I don't think the container should be a component; but I do think the container should be application / module specific. And not a global static.
It means less global state outside the application object.