Magento 2 Preferences is used by the Magento 2 object manager to extend the default implementation. You can use preferences in Magento 2 to implement some interfaces or to rewrite/override the existing PHP classes and their methods.
In this article, you'll learn how to do it and discover useful examples that will help you along the way.
Overriding classes in Magento 2
If you want to rewrite existing class methods with Magento preference follow the steps below:
1. Create the etc/di.xml file in your extension folder:
app/code/MyCompany/ModuleName/etc/di.xml
2. Add this code to it:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Checkout\Block\Onepage\Success" type="MyCompany\ModuleName\Block\Onepage\Success" />
</config>
Use attribute "for" in the "preference" tag to define the PHP class that you want to override. Use attribute "type" to define the PHP class that will be used instead of the original one.
3. Create a new PHP file:
app/code/MyCompany/ModuleName/Block/Onepage/Success.php
with the class MyCompany\ModuleName\Block\Onepage\Success:
<?php
namespace MyCompany\ModuleName\Block\Onepage;
class Success extends \Magento\Checkout\Block\Onepage\Success
{
// new code here
}
3. Save the changes and compile dependency injection via CLI command:
bin/magento setup:di:compile
Make sure that the command was executed without the errors.
Important note: rewriting existing classes is not recommended since it often leads to conflicts. The conflicts often appeared on Magento 1 and still take place in Magento 2.
So if you still want to use Magento 2 preference for class overriding, you need the Conflict Detector that will help you identify class conflicts.
However, if it is possible, you can use observers or plugins for modifying existing classes logic instead of Magento preference.
Interface Implementing
To implement the interface in Magento 2, for example, the interface of your new Repository you need to:
1. Create the etc/di.xml file in your Magento extension.
2. Specify the Preference for the Interface and Type of the class that will implement the interface, like in the example:
<?xml version="1.0"?>
<config>
<preference for="MyCompany\ModuleName\Api\MyEntityRepositoryInterface" type="MyCompany\ModuleName\Model\MyEntityRepository" />
</config>
3. Create Model/MyEntityRepository.php with the code
<?php
namespace MyCompany\ModuleName\Model;
use MyCompany\ModuleName\Api\MyEntityRepositoryInterface;
class MyEntityRepository implements MyEntityRepositoryInterface
{
// class code here
}
4. Save the changes and compile dependency injection via CLI command:
bin/magento setup:di:compile