-
Notifications
You must be signed in to change notification settings - Fork 635
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
[FR] Use Craft::createObject instead of "new" Object #6097
Comments
We were just talking about how we need to start refactoring code in preparation for that, whether we go with Yii 3 or Laravel, etc., it seems DI is the way to go these days. |
Yeah I really don't want to make that decision. Of course you could bring back the Service Locator in Yii3 (only a one liner) but to choose between the ongoing trend/"best practice" and easy to use code can be quite difficult. In fact Craft can be moved to Yii3 even with all those upcoming breaking changes without that much effort to restructure logic. I searched all of your components and you avoided dependency cycles quite well but for example the Commerce package won't be that easy to refactor without a service locator because some classes would look like class Customers{
public function __construct(Carts $carts){}
}
//...
class Carts{
public function __construct(Customers $customers){}
}
// ...
$customers = Commerce::getInstance()->getCarts();
// fatal error, out of memory, Carts tries to create a Customers instance,
// Customers tries to create a Carts instance and so on Events can be migrated as well - it's just much more effort in my opinion. Behaviors such as Just my 2 cents, I know this was much offtopic so I could delete it if you don't like it |
Appreciate the pointers! The main reason we had brought it up recently was to make the code more testable, with the added benefit that it will help update to Yii 3 or switch frameworks down the road. |
@brandonkelly I know this is a bit late but please would you use I would love to extend your Customfield and change the All you need to do is to change $element = new $type();
Craft::configure($element, $config); to /** @var FieldLayoutElementInterface $element */
$config['class'] = $type;
$element = Craft::createObject($config); Here a working example with only 3 changes in your source Code and this custom class namespace modules\fieldlayoutelements;
use Craft;
class CustomField extends \craft\fieldlayoutelements\CustomField
{
public $sortable = 'JA';
public function settingsHtml()
{
$view = Craft::$app->getView();
$settingsHtml = parent::settingsHtml();
$settingsHtml .= $view->renderTemplateMacro('_includes/forms', 'textField', [
[
'label' => Craft::t('app', 'Is this field sortable via frontend?'),
'id' => 'sortable',
'name' => 'sortable',
'value' => $this->sortable,
'placeholder' => 'sortierbar',
],
]) ;
return $settingsHtml;
}
} |
@Anubarak Done! |
@brandonkelly Thank you so much. I added 2/3 other parts as well and added those in the changelog via pull request. |
Description
This is not really an issue for one single spot, but a general request for "coding style". I notice many times you create classes with the
new
keyword which makes it hard to fully use the potential of Yii2. Things like Exceptions and Queries don't need to be created via DI but especially components in your ComponentHelper could be created in that way to achieve Dependency Injection.I use Yii2 outside of the Craft world too and since the upcoming release (Yii3) is going to (kinda) drop the Service Locator my modules for Yii3 are going to drop all of the
Yii::$app->
lines as well. In order to prepare for that move tt would be awesome if Craft would let me do that easier by also using thecreateObject
method to allow me to pass dependencies.Of course if you are going to not use Yii3 in the future and use another Framework due to the heavy changes or if you are going to stay with Yii2 for the next years it won't make any differences for you,
PS I'm talking about this
The text was updated successfully, but these errors were encountered: