Infastidito da tonnellate di classi per DI nei costruttori di Magento 2 - c'è un modo migliore?


8

In questo momento sono infastidito di scrivere costruttori simili in massa come i seguenti nei miei moduli.

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 */
}

In molti molti casi ho bisogno di istanze delle stesse classi in tutto il mio modulo.

Quindi mi chiedevo se sarebbe stato un modo accettabile di usare una o due classi helper centrali, che forniscono le classi necessarie, invece di definirle in ogni singolo costruttore.

Questo significa uno schema come questo:

Classe di aiuto

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;
    }
}

Il costruttore più corto

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 */
}

A questo punto non sono sicuro di dover affrontare grossi svantaggi in futuro causati da questa struttura. Sarebbe un modo accettabile per ridurre la quantità di definizioni DI?

Risposte:


7

Guarda \Magento\Framework\Model\Context, referenziato nel tuo esempio. Quello che descrivi è esattamente quello che fa. Magento utilizza Contextoggetti simili in tutto il nucleo per abbreviare gli elenchi DI.

L'unica cosa da tenere a mente è che questo non dovrebbe essere usato per nascondere cattive decisioni architettoniche . Dovresti considerare se ciascuna delle classi di cui hai bisogno "in tutto il tuo modulo" è davvero necessaria e, in tal caso, se esiste un modo alternativo di organizzare il tuo codice per raggiungere meglio lo stesso obiettivo. È facile introdurre problemi di prestazioni non intenzionali.


bene sì ... non potrebbe essere usato per "nascondere le cattive decisioni architettoniche" il mio punto più grande è la quantità di aiutanti che devo usare (i miei aiutanti personali e quelli di base) che le classi di contesto mi sono sembrate fare esattamente quello che hai detto, Non ne ero proprio sicuro. grazie 4 consigli
bukart

Quindi, in parole Contextpovere , le classi sono classi Magento che comprendono intere sezioni di Magento? vale a dire Contesto categoria, aiuterà a gestire Aggiungi / Modifica / Rimuovi / Visualizza categorie senza la necessità di importare più classi per fare la stessa azione?
MackieeE,

@MackieeE No, non del tutto. Comprendono alcune delle dipendenze di Magento per la determinata classe che stai osservando. Di solito sono piuttosto astratti / lontani dalla catena dell'eredità, non specifici per una particolare classe finale (come la Categoria). Se guardi \Magento\Catalog\Model\Category, vedrai che include lo stesso che \Magento\Framework\Model\Contextho menzionato - in realtà non c'è nulla in merito alle categorie. Stai cercando un repository: dai un'occhiata \Magento\Catalog\Api\CategoryRepositoryInterface.
Ryan Hoerr,

4

Sono abbastanza sicuro che non sei l'unico in questo caso e in qualche modo capisco perfettamente perché hai pensato di farlo.

Per me, il problema principale che vedo con tale approccio è che perdi uno dei principali vantaggi dell'iniezione di dipendenza, che è quello di sapere subito da cosa dipende la tua classe quando controlli il costruttore.

Un altro importante vantaggio di Dependency Injection è che semplifica il test del codice in un framework automatizzato. Nel tuo caso, questo è sicuramente un aspetto negativo.

Questi sono i due motivi che emergono ma potrebbero essercene di più.

EDIT: Aggiungerò solo una citazione di Alan Kent (che fa parte di Magento) che puoi trovare nei commenti di questa domanda :

In genere scoraggio i metodi di lancio in una classe di supporto che non sono correlati. È meglio avere classi separate che rappresentano scopi reali. O utilizzare metodi statici, nel qual caso non è necessario un costruttore (il codice chiamante è responsabile di ottenere handle per le strutture di dati necessarie).


Considerando che condivido con tutto il cuore le ragioni di cui sopra. Tuttavia, come principiante di Magento, sembra che ci sia una grande curva di apprendimento per imparare quali classi sono richieste e dipendono l'una dall'altra prima che tu possa iniziare a sviluppare.
MackieeE,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.