Comments (7)
I would like to always use $this->app to avoid static calls.
That's the good approach :) We would like too!
But it requires substantial rework of many of yii core classes.
This work is in progress and meanwhile we've presented deprecated Yii::getApp()
to have framework functional.
So general idea is simple: don't use deprecated methods, find better solutions, ask when in doubt.
from yii-core.
We are working on reducing static access to application as well.
We have already injected application in objects where it was easier to do it terms of architecture, but in some places we have not reached a mutual agreement on how to redo it, so you still see static calls.
from yii-core.
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().
from yii-core.
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.
from yii-core.
@antonprogz You have a very strong opinion but few arguments.
On the other side arguments for changes being done are well known.
You can google for:
- service locator is anti-pattern
- DI container should not be used explicitly
- static calls are considered bad
- global variables (Yii::$app) considered harmful
Please, do not restrict developers
This is a good argument. The idea was to empower developer, not constrain :)
At the 3.0 release all the old methods will still be available (possibly renamed). But deprecated - not recommended to use.
And I think at some time in future old methods will be moved to yii-legacy
package to have the framework core clean but old stuff available for conservative developpers.
change the whole philosophy, do you admit that
What philosophy do you think is changed?
Could you please collect your thoughts for we could discuss it in a constructive manner.
from yii-core.
Could you please collect your thoughts for we could discuss it in a constructive manner.
service locator is anti-pattern
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:
- Constructors, polluted by so-called 'transitional dependencies':
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);
}
}
- Creation of not requred instances.
In the first example above, the Foo oject will be always created, no matter if the Inventory::items() method is called.
"Yii creates objects that are in use only" - is the one of the Yii's key exclamations. SL supports that, Constructor Injection - doesn't. In Java and C# it is not a problem, but PHP dies after each request and can't pre-create and reuse dependency graphs. I think Constructor DI could reduce perfomance and increase memory consumption in large PHP web apps.
DI container should not be used explicitly
If it is used as a service locator, that's not a bad stuff.
static calls are considered bad
In general, its true, but for one singleton (SL) static methods are ok.
global variables (Yii::$app) considered harmful
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:
- If Yii team wants to avoid static calls and SL, how a db connection instance will be injected into new ActiveRecord instances?
$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.
- How to inject custom dependencies into ActiveRecord instances and its behaviors without Service Locator and static calls (Yii::createObject(), Yii::ensureObject())? Destroying this way of DI could totally reduce encapsulation and disavow the plain old "that models, thin controllers" recomendation.
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.
from yii-core.
I would like to always use $this->app to avoid static calls.
That's the good approach :) We would like too!
But it requires substantial rework of many of yii core classes.
This work is in progress and meanwhile we've presented deprecatedYii::getApp()
to have framework functional.So general idea is simple: don't use deprecated methods, find better solutions, ask when in doubt.
How to use di instead for $this->app in models, and do not use Yii::getApp(). @hiqsol
from yii-core.
Related Issues (20)
- 我认为yii3最应该解决的就是composer包过大的问题 HOT 2
- Should not require yii-web HOT 11
- Enhancement: BaseJson::decode supports decode options HOT 1
- Discuss: Do we still need controllers? HOT 2
- Enhancement: StringHelper::isEmpty() HOT 7
- can't visit yii forum site HOT 1
- Review helpers naming and usage HOT 33
- Url::ensureScheme should fail hard for non absolute paths HOT 2
- What is the current dependency between repo? HOT 20
- Yii3 assets path not correctly reference if installed in subfolder HOT 2
- SOLID compliance HOT 3
- cannot use @web or @webroot in config. HOT 53
- Deal with relative links in Formatter::asUrl() HOT 4
- Nested model attribute label issue HOT 12
- Custom reference syntax to class or class member in comments make impossible to navigate in IDE HOT 19
- Change namespace to Yiisoft\Core? HOT 8
- When will yii3 be released? HOT 1
- Request to separate FileHelper from yii-core HOT 19
- Pack requirements checker into separate package HOT 1
- Repo merges into a repo and then splits HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from yii-core.