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.