Как в Magento 2 подписать на событие объект-одиночку?

события

(Дмитрий Федюк) #1

В Magento 1 по умолчанию все подписчики на системные события являются объектами-одиночками.
Это значит, что при повторном наступлении системного события Magento не создавала новый экземпляр подписчика, а использовала прежний экземпляр.
Например:

<config>
    <global>
        <events>
            <controller_front_init_before>
                <observers>
                    <df_core__controller_front_init_before>
                        <class>df_core/dispatcher</class>
                        <method>controller_front_init_before</method>
                    </df_core__controller_front_init_before>
                </observers>
            </controller_front_init_before>
        </events>
    </global>
</config>

В Magento 1, чтобы система при каждом наступлении события система создавала новый экземпляр подписчика, надо было явно указать параметр <type>model</type>, например:

<config>
    <global>
        <events>
            <controller_front_init_before>
                <observers>
                    <df_core__controller_front_init_before>
                        <type>model</type>
                        <class>df_core/dispatcher</class>
                        <method>controller_front_init_before</method>
                    </df_core__controller_front_init_before>
                </observers>
            </controller_front_init_before>
        </events>
    </global>
</config>

В Magento 2 все подписчики на системные события тоже по умолчанию являются объектами-одиночками.
На magento.stackexchange.com в ответе-решении с 10 положительными голосами утверждается прямо обратное, но там неправда, в чём можно убедиться, посмотрев код:

Итак, следующий код подписывает на событие объект-одиночку:

<config 
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
    xsi:noNamespaceSchemaLocation='../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd'
>
    <event name='store_collection_load_before'>
        <observer 
            name='rm_core' 
            instance='Rm\Core\Model\Dispatcher'
            method='storeCollectionLoadBefore'
        />
    </event>
</config>

Чтобы в Magento 2 система использовало при каждом новом наступлении события новый объект , надо указать значение false для атрибута shared, например:

<config 
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
    xsi:noNamespaceSchemaLocation='../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd'
>
    <event name='store_collection_load_before'>
        <observer 
            name='rm_core' 
            instance='Rm\Core\Model\Dispatcher'
            method='storeCollectionLoadBefore'
            shared='false'
        />
    </event>
</config>

Вообще, для всех типов настроек Magento 2 true является значением по умолчанию для атрибута shared.


(Дмитрий Федюк) #2

С октября 2015 года порядок подписки на события и обработки событий в Magento 2 изменились: Как в Magento 2 подписаться на событие и обработать его