Ok, ontem tivemos uma grande conversa com outras pessoas da comunidade Magento sobre o uso direto do ObjectManager
nas aulas / modelos .
Eu já estou ciente dos motivos pelos quais não devemos usar o ObjectManager diretamente, citando Alan Kent :
Existem várias razões. O código funcionará, mas é uma prática recomendada não fazer referência diretamente à classe ObjectManager.
- Porque dizemos isso! ;-) (melhor expresso como código consistente é bom código)
- O código pode ser usado com uma estrutura de injeção de dependência diferente no futuro
- O teste é mais fácil - você passa argumentos simulados para a classe necessária, sem precisar fornecer um ObjectManager falso
- Mantém as dependências mais claras - é óbvio do que o código depende via lista de construtores, em vez de ter dependências ocultas no meio do código
- Incentiva os programadores a pensarem melhor em conceitos como encapsulamento e modularização - se o construtor crescer, talvez seja um sinal de que o código precisa ser refatorado
Pelo que vi no StackExchange, muitas pessoas tendem a procurar a solução fácil / curta / não recomendada, por exemplo, algo como isto:
<?php
//Get Object Manager Instance
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Load product by product id
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($id);
Em vez de passar pelo doloroso, mas recomendado, processo de:
- criando um módulo
- declarando preferências
- injetar dependências
- declarar um método público
No entanto, e aqui está o dilema, os arquivos principais do Magento 2 costumam chamar o ObjectManager diretamente . Um exemplo rápido pode ser encontrado aqui: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
Então, aqui estão as minhas questões:
- Por que o Magento está fazendo o que eles recomendam que não façamos? Isso significa que existem alguns casos em que devemos usar o
ObjectManager
diretamente ? Se sim, quais são esses casos? - Quais são as consequências de usar o ObjectManager diretamente ?
The intent of zend-servicemanager is for use as an Inversion of Control container. It was never intended as a general purpose service locator [...]
. O que também se aplica ao M2. Verifique também a There are valid use cases
seção, que novamente se aplica aqui também.