Magento 2 CRUD / 추상 모델에 의존성 주입


12

Magento 2 CRUD 모델에 의존성을 주입 할 수 있습니까?

즉, Magento 2에는 기본 추상 모델 클래스가 Magento\Framework\Model\AbstractModel있습니다. 간단한 Create, Read, Update, Delete 모델 객체를 만들려면이 클래스를 자신의 클래스로 확장하십시오.

class Foo extends Magento\Framework\Model\AbstractModel
{
}

모델의 __construct방법에 의존성을 주입 할 수 있습니까? 시도하면 다음과 같은 오류가 발생합니다.

치명적인 오류 : 추상 클래스 Magento \ Framework \ Model \ ResourceModel \ AbstractResource를 인스턴스화 할 수 없습니다.

범인은 님 AbstractModel의 __construct방법 인 것 같습니다 .

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\Registry $registry,
    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {

이 생성자 ( Magento\Framework\Model\ResourceModel\AbstractResource, Magento\Framework\Data\Collection\AbstractDb) 에는 Magento 개체 관리자 인터페이스 가 아닌 두 가지 유형 힌트가 있습니다. 그들은 추상 수업입니다. 이 클래스를 확장하고 주입 된 종속성을 추가하려고하면

class Foo extends Magento\Framework\Model\AbstractModel
{
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = [],
        \Package\Module\Model\Mine $mine,

    ) {
        //...
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);

    }
}

객체 관리자가 추상 클래스를 인스턴스화하려고 시도하면 마 젠토가 중단됩니다.

나는 객체 의존성을 추상 클래스들 앞에서 움직여서 이것을 고칠 수있다

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

        \Package\Module\Model\Mine $mine,

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

그러나 이로 인해 인수 순서가 변경되었습니다. 완전히 객체 관리 된 클래스에서는 문제가되지 않습니다. 그러나 이러한 추상 클래스 유형 힌트가 존재한다는 사실은 Magento 시스템의 일부가 객체 관리자 나 DI를 통해 수동으로 CRUD 객체를 인스턴스화 하고 해당 특정 순서로 유형 힌트를 준수하는 객체를 전달 한다는 것을 의미합니다 .

안전한가요? 즉, 추상 모델 생성자의 이러한 추상 클래스는 레거시 코드 일 뿐이며 사용되지 않습니까? 아니면 시스템의 일부가 여전히 이것을 사용하여 CRUD 모델에 의존성을 주입 할 수 없습니까?

답변:


9

우선 모든 생성자는 class의 private api입니다. 생성자 함수는 특별한 의미를 가지며 부모 클래스와 동일한 인수 목록 / 순서를 가질 필요는 없습니다.

Magento 2 CRUD 모델에 의존성을 주입 할 수 있습니까?

네 물론 이죠

안전한가요?

예, 그러나 Magento Object Manager는 모든 선택적 매개 변수가 목록 끝에 배치되고 선택적 이후 필수 매개 변수는 해결되지 않는다고 가정합니다.

$ resource, $ resourceCollection 인수는 레거시이지만 여전히 Model 클래스에서 널리 사용됩니다. 대부분의 모델은 이와 같은 코드를 사용하여 리소스 및 컬렉션 클래스를 초기화합니다.

protected function _construct() { 
    $this->_init('Magento\AdminNotification\Model\Resource Model\Inbox'); 
}

이것이이 매개 변수가 선택적인 이유입니다. 그러나 예를 들어 단위 테스트에서는 대체 실현을 허용하기 위해 생성자에 리소스 또는 컬렉션 모의 객체를 전달합니다.


@Kanday Magento의 엔지니어링 / 아키텍처 부서는 핵심 클래스의 생성자 순서와 관련이 없다는 공개 성명을 발표 한 적이 있습니까? 아니면 그 일을하는 대부분의 사람들의 희망일까요?
— Alan Storm

나는 그것을 "무의미한"것으로 부르지 않을 것이다. OM 만 필요한 인수를 생성자에 전달하고 부모 클래스의 순서에 의존하지 않습니다. 또한, IN은 매개 변수 이름을 사용하므로 이제는 변경하지 않는 것이 좋습니다 (원하는대로 매개 변수 이름을 변경할 수있는 PHP 언어와 다릅니다)
— KAndy

당신이 무슨 말을하는지 잘 모르겠습니다. 미래의 어느 시점에서 핵심 Magento 시스템 코드가 인수 / 매개 변수 순서를 다시 중요하게 취급하기 시작할 수 있다고 말하고 있습니까?
— Alan Storm

나는 믿습니다
— KAndy

다시 감사합니다! FWIW, Google 직원에게는 이것이 안전한 일인 것 같습니다. 내가 알 수 있듯이 생성자 매개 변수 순서를 가정하여 모델을 자동으로 맹목적으로 인스턴스화하는 Magento 시스템 코드가 없습니다.
— Alan Storm

6

안전한 것으로 보입니다. 적어도 magento는 여러 곳에서이 작업을 수행하고 있습니다. 예제는 다음의 (비 배타적) 클래스 목록에서 __construct 메소드를 참조하십시오.

  • \ 마 젠토 \ 테마 \ 모델 \ 테마 \ 파일
  • \ 마 젠토 \ 테마 \ 모델 \ 디자인
  • \ 마 젠토 \ 판매 \ 모델 \ 주문 \ Creditmemo

불행히도, 나는 당신의 질문의 다른 부분에 대답 할 수 없습니다.


4
  1. 모델을 어떻게 사용합니까?
  2. 귀하의 경우에는 $mineA는 필요 하지만, 매개 변수 $resource, $resourceCollection그리고 $data있습니다 옵션 . 선택적 매개 변수는 항상 마지막에 가야합니다. 그렇지 않으면 선택적에서와 같이 사용할 수 없습니다. 따라서 $mine선택적 매개 변수보다 먼저 지정 해야합니다.

이러한 추상 매개 변수를 제외하고는 의존성 주입 매개 변수가 아니며 Magento 핵심 시스템 코드가 해당 매개 변수가 $mine대기열의 앞쪽으로 이동할 것으로 예상하면 오류가 발생합니다. Magento 핵심 시스템 코드 가 이를 사용 하지 않는 이유는 무엇입니까? 그것이 내가 바닥에 가려고하는 질문입니다. 매개 변수를 이동 한 상태에서 모델을 사용할 수 있다고해서 안전하지는 않습니다.
— Alan Storm

일부 모델은 여전히 ​​이러한 선택적 매개 변수를 사용하여 사용자 정의 자원 모델을 전달할 수 있습니다. 예를 들면, github.com/magento/magento2/blob/develop/app/code/Magento/…
— BuskaMuza

Magento는 리플렉션을 사용하여 매개 변수가 선택적인지 여부를 결정합니다. 그리고 PHP는 필요한 모든 매개 변수를 필수 매개 변수 앞에 서있는 것으로 간주 합니다 . 따라서 $mine선택적 매개 변수보다 먼저 이동하면 실제로 선택적이되고 Magento는 기본값 ( null, array()) 만 전달합니다 . 선택적 매개 변수 뒤에 필수 매개 변수를 넣는 경우, PHP는 선택적 매개 변수를 필수 매개 변수로 간주하고 Magento는이를 인스턴스화하려고 시도했지만 선호하는 것은 없습니다.
— BuskaMuza

혼란스럽고 어쩌면 모델 클래스 내에서 추상 클래스를 처리하는 대신 추상 클래스에 대한 환경 설정을 설정할 수 있다는 데 동의합니다. 따라서 실제 물체는 항상 주입됩니다.
— BuskaMuza
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.