Agacé par des tonnes de classes pour DI dans les constructeurs de Magento 2 - y a-t-il une meilleure façon?


8

En ce moment, je suis ennuyé d'écrire des constructeurs similaires en masse comme les suivants dans mes modules.

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\Registry $registry,

    /* ... */

    \Foo\Bar\Model\Baz $baz,

    /* ... */

    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->registry = $registry;

    /* ... */

    $this->baz = $baz;

    /* ... */

    /* some awesome stuff */
}

Dans de nombreux cas, j'ai besoin d'instances des mêmes classes partout dans mon module.

Je me demandais donc si ce serait une façon acceptable d'utiliser une ou deux classes d'assistance centrales, qui fournissent les classes nécessaires, au lieu de les définir dans chaque constructeur.

Cela signifie un modèle comme celui-ci:

Classe d'assistance

namespace Foo\Bar\Helper

class Main
{
    protected $baz;



    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,

        /* ... */

        \Foo\Bar\Model\Baz $baz,

        /* ... */
    ) {
        $this->registry = $registry;

        /* ... */

        $this->baz = $baz;

        /* ... */

        /* some awesome stuff */
    }



    public function getBazInstance()
    {
        return $this->baz;
    }
}

Le constructeur le plus court

public function __construct(

    \Foo\Bar\Helper\Main $mainHelper,

    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->mainHelper = $mainHelper;

    /* some awesome stuff */
}

À ce stade, je ne sais pas si je devrai faire face à de gros inconvénients à l'avenir causés par cette structure. Serait-ce un moyen acceptable de réduire le nombre de définitions d'ID?

Réponses:


7

Découvrez \Magento\Framework\Model\Context, référencé dans votre exemple. Ce que vous décrivez est exactement ce qu'il fait. Magento utilise des Contextobjets similaires dans tout le noyau pour raccourcir les listes DI.

La seule chose à garder à l'esprit est que cela ne doit pas être utilisé pour cacher de mauvaises décisions architecturales . Vous devez vous demander si chacune des classes dont vous avez besoin «partout dans votre module» est vraiment nécessaire, et si oui, s'il existe une autre façon d'organiser votre code qui permettrait de mieux atteindre le même objectif. Il est facile d'introduire des problèmes de performances involontaires.


eh bien oui ... ça ne devrait pas être utilisé pour "cacher les mauvaises décisions architecturales" mon plus grand point est la quantité d'aides que je dois utiliser (mes propres aides et celles de base) les classes Context m'ont semblé faire exactement ce que vous avez dit, Je n'étais tout simplement pas sûr. thx 4 conseils
bukart

Donc, en termes simples, les Contextclasses sont des classes Magento qui englobent des sections entières de Magento? c'est-à-dire le contexte de catégorie, aidera à gérer l'ajout / modification / suppression / affichage des catégories sans avoir besoin d'importer plusieurs classes pour effectuer la même action?
MackieeE

@MackieeE Non, pas tout à fait. Ils englobent certaines des dépendances de Magento pour la classe donnée que vous regardez. Ils sont généralement plutôt abstraits / loin dans la chaîne d'héritage, non spécifiques à une classe de fin particulière (comme Catégorie). Si vous regardez \Magento\Catalog\Model\Category, vous verrez qu'il comprend le même que celui que \Magento\Framework\Model\Contextj'ai mentionné - il n'y a en fait rien du tout dans les catégories. Vous recherchez un référentiel - jetez un œil à \Magento\Catalog\Api\CategoryRepositoryInterface.
Ryan Hoerr

4

Je suis presque sûr que vous n'êtes pas le seul dans ce cas et d'une certaine manière, je comprends parfaitement pourquoi vous avez pensé à faire cela.

Pour moi, le principal problème que je vois avec une telle approche est que vous perdez l'un des principaux avantages de l'injection de dépendance qui est de savoir immédiatement de quoi dépend votre classe lors de la vérification du constructeur.

Un autre avantage important de l'injection de dépendance est qu'il rend le code plus facile à tester dans un cadre automatisé. Dans votre cas, c'est certainement un inconvénient.

Ce sont les deux raisons qui se présentent, mais il peut y en avoir plus.

EDIT: Je vais juste ajouter une citation d'Alan Kent (qui fait partie de Magento) que vous pouvez trouver dans les commentaires de cette question :

Je déconseille généralement de lancer des méthodes dans une classe d'assistance qui ne sont pas liées. Il est préférable d'avoir des classes séparées qui représentent des objectifs réels. Ou utilisez des méthodes statiques, auquel cas il n'y a pas besoin de constructeur (le code appelant est responsable d'obtenir les descripteurs des structures de données nécessaires).


Alors que je suis entièrement d'accord sur les raisons ci-dessus. Cependant, en tant que novice de Magento moi-même, il semble qu'il y ait une grande courbe d'apprentissage pour savoir quelles classes sont requises et dépendent les unes des autres avant de commencer à développer.
MackieeE
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.