Tìm hiểu về di.xml trong Magento 2

Giới thiệu

di.xml (dependency injection) là một trong những tập tin quan trọng trong Magento 2 khi xây dựng module/component, được dùng để khai báo các thành phần phụ thuộc của một chiếc module . Tập tin di.xml do Object Manager của Magento 2 quản lý và sử dụng. Vậy di.xml trong Magento 2 có thể làm được những gì:

  • Bạn có thể sử dụng di.xml để ghi đè lên một class cụ thể với preference node.
  • Bạn có thể tạo mới hoặc thay thế một đối số trong constructor của một class với arguments.
  • Thay đổi hành vi của một class với before, after và arround Plugin.
  • Tạo một class con của một class khác với virtualType node.

Có thể mô tả ngắn gọn như sau: khi gọi Class nào đó, thay vì dùng new Class, họ sẽ dùng ReflectionClass (là một class built-in của PHP), class này sẽ tìm xem class ta cần gọi phụ thuộc vào những đối tượng nào, từ đó gọi những đối tượng đó ra. Và để cho ngắn gọn, Magento 2 sẽ dùng di.xml để thay đổi những class cần gọi.

Nếu các bạn thay đổi code của mình trong thư mục riêng app/code/VendorName/… thì không sao, nhưng nếu các bạn muốn thay đổi tham số, hay bất kì cái gì mặc định mà thuộc core của Magento 2, bạn cần dùng di.xml để thay đổi. Khi đọc code module cũng vậy, những gì bạn đọc trong tập tin .php có thể sẽ không đúng, bạn phải đọc cả trong tập tin di.xml nữa và kết hợp cả 2 với nhau. Chúng ta sẽ làm rõ điều này trong nội dung dưới đây. Let’s go !

Phạm vi của tập tin di.xml trong Magento 2

Mỗi tập tin di.xml có thể nằm ở backend hoặc frontend hoặc có thể nằm trực tiếp trong thư mục etc. Magento sẽ đọc tất cả các tập tin di.xml có trong hệ thống và sau đó merge(hợp nhất) tất cả chúng lại bằng cách nối các nodes lại với nhau. Các nodes ở đây chính là các thẻ như: type, virtualType, plugin, preference.

Thẻ type trong di.xml

Đầu tiên chúng ta hãy xem qua đoạn code sau:

<type name="Magento\Customer\Model\ResourceModel\Group" shared="false">
    <arguments>
        <argument name="groupManagement" xsi:type="object">Magento\Customer\Api\GroupManagementInterface\Proxy</argument>
    </arguments>
</type>

Ở đây chúng ta có thể hiểu rằng chúng ta đang tạo mới một đối tượng có tên là groupManagement với class là Proxy như là một đối số, và chúng ta sẽ truyền cái đối số này vào contructor của class Group.

Ở đây chúng ta cũng có thể thay thế một đối số trong contructor của một class. Để các bạn có một cái nhìn tổng quan hơn thì tôi sẽ lấy một ví dụ đơn giản như sau: Giả sử tôi có một class có tên là MageStore\HelloWorld\Block\Index và trong contructor của tôi đang có một biến $a = 1 như đoạn code bên dưới:

protected $a;
 
    public function __construct($a = 1)
    {
        $this->a = $a;
    }

Biến a của tôi đang bằng 1 và tôi muốn sử dụng thẻ type trong di.xml để thay thế đối số này thành 2 chẳng hạn thì tôi phải làm sao. Lưu ý ở đây chỉ là ví dụ để các bạn có thể hiểu được nó làm việc như thế nào thôi nhé.

 <type name="ViMagento\HelloWorld\Block\Index">
    <arguments>
        <argument name="a" xsi:type="string">2</argument>
    </arguments>
</type>

Và ở trên tôi đã khai báo một file di.xml, tôi sử dụng thẻ type và truyền vào class mà tôi muốn thay đổi đối số. Sau đó sử dụng arguments khai báo một biến là a trùng với biến ở contructor mà tôi muốn thay thế có giá trị là 2 và kiểu dữ liệu là string. Đó là cách mà thẻ type trong tập tin di.xml hoạt động.

Thẻ virtualType trong di.xml

virtual type có tạo một class ảo của một class cha. Hay nói cách khác virtualType có thể dùng để tạo một class con của một class khác mà không làm ảnh hưởng đến class đó.

<virtualType name="moduleConfig" type="Magento\Core\Model\Config">
    <arguments>
        <argument name="type" xsi:type="string">system</argument>
    </arguments>
</virtualType>
<type name="Magento\Core\Model\App">
    <arguments>
        <argument name="config" xsi:type="object">moduleConfig</argument>
    </arguments>
</type>

Đoạn code trên đã sử dụng virtualType để tạo một class con có tên là moduleConfig của class cha là Config. Giống như class moduleConfig kế thừa từ class Config và nó tất cả những đặc tính của class cha vậy. Chúng thường tạo ra class ảo như thế và truyền vào thẻ type để thay thế một đối số trong contructor của một class.

Plugin trong di.xml

Plugin thường được sử dụng để tác động đến hành vi của một class hay phương thức bằng cách chặn lệnh gọi đến phương thức ban đầu và chạy code của chúng ta. Có ba loại plugin là before, after và arround.

<type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
    <plugin name="sortby_extend_default_sort_filters" type="ViMagento\HelloWorld\Plugin\Block\Toolbar" />
</type>

Kết luận

Ở trên là một số kiến thức về di.xml, hi vọng nó có ích với mọi người.
Have fun coding !

4 Likes