-
Notifications
You must be signed in to change notification settings - Fork 75
Doubt Yii 3.0 ($this->app or Yii::getApp()). #11
Comments
We are working on reducing static access to application as well. |
That's the good approach :) We would like too! So general idea is simple: don't use deprecated methods, find better solutions, ask when in doubt. |
What a terrible thing you are doing! Yii was originally built on top of static service locator pattern, and getting any dependency in any place gived us great level of flexibility. For people who are against this there is the Symfony framework. Please, do not restrict developers like Symfony does. Besides, huge amount of rewriting and redesigning should be done to remove Yii::getApp() (Yii::$app) from the framework completely and getting this job done will change the whole philosophy, do you admit that? And how about Yii::ensureObject(), and Yii::createObject()? Do you want to deprecate them too? If not, I don't see any reason for the Yii::getApp() deprecation, because any dependency is still available statically from Yii::ensureObject(). |
Injecting the whole Application instance doesn't differ a lot from getting it statically, because the client class is still tightly coupled to yii's Application class. I wonder, if you could explain the benefits. |
@antonprogz You have a very strong opinion but few arguments.
This is a good argument. The idea was to empower developer, not constrain :)
What philosophy do you think is changed? |
I don't agree with that. Service Locator was described by Martin Fowler, and who proclaimed it an anti-pattern? I consider SL as a one of the DI patterns with it's pros and cons. Constructor injection has it's own drawbacks too, for example:
class Item
{
private $dep;
private $data;
public function __construct(Foo $dep, array $data)
{
$this->dep = $dep;
$this->data = $data;
}
}
class ItemIterator
{
private $dep;
private $data_source;
public function __construct(Foo $dep, Iterator $data_source)
{
$this->dep = $dep;
$this->data_source = $data_source;
}
public function current(): Item
{
$data = $this->data_source->current();
return new Item($this->dep, $data);
}
}
class Inventory
{
private $api;
private $dep;
public function __construct(Foo $dep, $api)
{
$this->dep = $dep;
$this->api = $api;
}
public function items(): Iterator
{
return new ItermIterator($this->dep, $this->api->fetchInventoryData());
}
} Item class has the Foo dependency to meet it's own needs. In order to create new Item objects, Inventory and ItemIterator should pass the Foo object through them. With SL it's not an issue: class Item
{
private $dep;
public function __construct()
{
$this->dep = DI::instance()->get('foo');
Assert::isInstanceOf($this->dep, Foo::class);
}
}
In the first example above, the Foo oject will be always created, no matter if the Inventory::items() method is called.
If it is used as a service locator, that's not a bad stuff.
In general, its true, but for one singleton (SL) static methods are ok.
Global variables - yes. Singletons - no. Singletons could be mocked with ease. Signletons could not be replaced suddently: Yii::app() and YII::getApp() are not global variables. Why should they be marked as deprecated? That's my opinion about your arguments). Here are some additional questions about the new 3.0 ROADMAP:
$product = new Product($this->db); I think this is not an option, passing the Connection instance around could pollute the code and decrease readability. The same is actual for the other dependencies that are widely used, like logger, urlManager, authManager etc.
P.S. @qiangxue, the creator of Yii (and the first core team members, of course), invented an outstanding PHP framework. They carefully reconsidered all the OOP principles and patterns and created very productive toolkit. SL is the one of the main features this productivity was built on. |
How to use di instead for $this->app in models, and do not use Yii::getApp(). @hiqsol |
Hi, I have a question revising the Yii 3.0 code when I can use $this>app or Yii::getApp(), I see that in yiisoft/app/controller/sitecontroller.php using $this->app and in the Yii::getApp() in view,
I would like to always use $this->app to avoid static calls.
Thanks.
The text was updated successfully, but these errors were encountered: