Magento – Magento 2 Argument of preference constructor is also a preference, error

dependency-injectionmagento2

I'm overriding class Magento\Customer\Model\CustomerRegistry with my own preference. Then I create a preference for Magento\Customer\Api\CustomerRepositoryInterface, which has an argument in the constructor of type CustomerRegistry.

This is part of my di.xml:

<preference for="Magento\Customer\Model\CustomerRegistry"
                type="Tmo\Customer\Model\CustomerRegistryPreference" />
<preference for="Magento\Customer\Api\CustomerRepositoryInterface"
            type="Tmo\Customer\Model\ResourceModel\CustomerRepositoryPreference" />

Besides, Interceptor class created by Magento2 Dependency Injection is there with the proper argument of type CustomerRegistryPreference, however I'm getting the next error:

Recoverable Error: 
Argument 3 passed to Tmo\Customer\Model\ResourceModel\CustomerRepositoryPreference\Interceptor::__construct() 
must be an instance of Magento\Customer\Model\CustomerRegistry, 
instance of Tmo\Customer\Model\CustomerRegistryPreference given, 
called in /src/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php on line 181 and 
defined in /src/var/generation/Tmo/Customer/Model/ResourceModel/CustomerRepositoryPreference/Interceptor.php on line 12

I was expecting from Magento the correct dependency injection but I got that error.
Even if I delete the preference for Magento\Customer\Api\CustomerRepositoryInterface, I get the same error but in the core class:

Recoverable Error: 
Argument 3 passed to Magento\Customer\Model\ResourceModel\CustomerRepository\Interceptor::__construct() 
must be an instance of Magento\Customer\Model\CustomerRegistry, 
instance of Tmo\Customer\Model\CustomerRegistryPreference given, 
called in /src/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php on line 164 and 
defined in /src/var/generation/Magento/Customer/Model/ResourceModel/CustomerRepository/Interceptor.php on line 12

If I modify the class CustomerRepositoryPreference in the constructor changing the argument CustomerRegistry for CustomerRegistryPreference, the problem is solved, but in the second example when the preference was gone, I shouldn't modify the core class.

So my question is if there is a way to fix this error without touching the argument in the constructor???

Best Answer

I solved the problem. I explain it: I'm using preferences because I need to use or change the protected methods or attributes of core classes, so my preferences were a copy of those core classes.

Instead of being an exact copy or the original, the preferences which doesn't implements an interface, now extends from the core files and the problem is solved.

Example, before:

class CustomerRegistryPreference
{ }

Example, after:

class CustomerRegistryPreference extends \Magento\Customer\Model\CustomerRegistry
{ }

Example, implementing an interface:

class CustomerRepositoryPreference implements \Magento\Customer\Api\CustomerRepositoryInterface
{ }

Happy ending :)

Related Topic