Trong lập trình Magento 2, khái niệm Dependency Injection là một trong những thuật ngữ được nhắc nhiều nhất. Vậy Dependency Injection là gì? Ứng dụng như thế nào trong lập trình Magento. Trong bài viết trước chúng ta đã tìm hiểu về [Magento 2] Object Manager là gì? Cách thức hoạt động của Magento 2, bài viết này mình sẽ giới thiệu chi tiết về Dependency Injection (DI) nhé!
Dependency Injection là gì?
Theo document từ Adobe ở đây. Thì Dependency Injection (DI) là một phương pháp quản lý các phụ thuộc trong các ứng dụng lớn, và nó được sử dụng rộng rãi trong Magento 2.
Trong Magento 2, DI được sử dụng để quản lý các đối tượng và phụ thuộc giữa chúng, cho phép ứng dụng dễ dàng mở rộng và thay đổi. DI trong Magento 2 làm cho việc phát triển và bảo trì ứng dụng trở nên dễ dàng hơn và giảm thiểu sự phụ thuộc của các đối tượng trong ứng dụng.
Phân loại Dependency Injection
Có 3 loại DI trong Magento 2 bao gồm:
1. Constructor Injection
Constructor Injection được sử dụng để inject dependencies thông qua constructor của một class. Ví dụ dưới đây mô tả việc sử dụng Constructor Injection để inject một instance của class \Magento\Catalog\Api\ProductRepositoryInterface
vào class MyProduct
namespace MyVendor\MyModule\Model;
use Magento\Catalog\Api\ProductRepositoryInterface;
class MyProduct
{
protected $productRepository;
public function __construct(ProductRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
}
2. Setter Injection
Setter Injection được sử dụng để inject dependencies thông qua các setter method của một class. Ví dụ dưới đây mô tả việc sử dụng Setter Injection để inject một instance của class \Magento\Framework\Logger\Logger
vào class MyLogger
namespace MyVendor\MyModule\Model;
use Psr\Log\LoggerInterface;
class MyLogger
{
protected $logger;
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
3. Interface Injection
Interface Injection được sử dụng để inject dependencies thông qua một interface. Ví dụ dưới đây mô tả việc sử dụng Interface Injection để inject một instance của class \Magento\Framework\App\RequestInterface
vào class MyRequest
thông qua interface \Magento\Framework\App\RequestInterface
namespace MyVendor\MyModule\Model;
use Magento\Framework\App\RequestInterface;
class MyRequest
{
protected $request;
public function __construct(RequestInterface $request)
{
$this->request = $request;
}
}
Lưu ý: Cách tốt nhất để sử dụng Dependency Injection là thông qua Constructor injection. Constructor injection là phương pháp giúp đưa các dependency vào trong class thông qua các tham số của constructor. Khi một đối tượng được tạo ra, Magento 2 sẽ tự động tìm kiếm các dependency và tiêm chúng vào qua constructor.
Những thành phần trong Dependency Injection
Bao gồm 3 phần chính đó là:
1. Interface (Giao diện)
Interface là một khuôn mẫu xây dựng tiêu chuẩn và quy chuẩn các phương thức được sử dụng bởi các class khác để tương tác với nó. Interface định nghĩa những phương thức và thuộc tính cần thiết để các class khác có thể sử dụng chúng một cách đồng nhất.
Ví dụ: Interface \Magento\Catalog\Api\ProductRepositoryInterface
được sử dụng để quản lý sản phẩm. Nó định nghĩa các phương thức chính để tạo, đọc, cập nhật và xóa các sản phẩm trong cửa hàng.
2. Class (Lớp)
Class là một đối tượng được xác định bởi các thuộc tính và phương thức của nó. Một class có thể chứa các thuộc tính và phương thức để thực hiện các chức năng cụ thể và sử dụng các interface khác để tương tác với các class khác.
Ví dụ: Class \Magento\Catalog\Model\ProductRepository
sử dụng interface \Magento\Catalog\Api\ProductRepositoryInterface
để tạo, đọc, cập nhật và xóa sản phẩm trong cửa hàng.
3. Configuration (Cấu hình)
Configuration định nghĩa cách các class phụ thuộc vào nhau thông qua các giao diện và các tham số khác.
Ví dụ: File di.xml (Dependency Injection configuration file) định nghĩa các class và interface được sử dụng trong Magento 2. Trong đó, có một phần cấu hình như sau:
<type name="Magento\Catalog\Api\ProductRepositoryInterface">
<arguments>
<argument name="entityFactory" xsi:type="object">Magento\Catalog\Model\ProductFactory</argument>
<argument name="collectionFactory" xsi:type="object">Magento\Catalog\Model\ResourceModel\Product\CollectionFactory</argument>
</arguments>
</type>
Trong phần này, class \Magento\Catalog\Api\ProductRepositoryInterface
phụ thuộc vào class \Magento\Catalog\Model\ProductFactory
và \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
thông qua các tham số của nó. Khi cần sử dụng các phương thức của các class này, Magento sẽ tự động khởi tạo và cung cấp chúng cho class được yêu cầu thông qua Dependency Injection.
Cách thức hoạt động của Dependency Injection
Các bước cơ bản của DI trong Magento 2 như sau:
Bước 1: Định nghĩa một lớp cần phụ thuộc vào đối tượng khác thông qua constructor hoặc phương thức khởi tạo setter.
namespace Vendor\Module\Block;
use Vendor\Module\Model\ExampleModel;
class ExampleBlock
{
protected $exampleModel;
public function __construct(
ExampleModel $exampleModel
) {
$this->exampleModel = $exampleModel;
}
}
Bước 2: Đăng ký lớp này với hệ thống DI bằng cách sử dụng tệp di.xml. Tệp này cấu hình các phụ thuộc và liên kết giữa các lớp.
<!-- File: Vendor/Module/etc/di.xml -->
<config>
<type name="Vendor\Module\Block\ExampleBlock">
<arguments>
<argument name="exampleModel" xsi:type="object">Vendor\Module\Model\ExampleModel</argument>
</arguments>
</type>
</config>
Giải thích:
Trong đoạn mã trên, ta đang đăng ký lớp ExampleBlock
với DI, với exampleModel
là đối số được truyền vào constructor và được cấu hình để sử dụng đối tượng Vendor\Module\Model\ExampleModel
.
Khi Magento 2 tạo một thể hiện của lớp ExampleBlock
, nó sẽ tự động tạo ra một thể hiện của ExampleModel
và truyền nó vào ExampleBlock
thông qua constructor.
Với DI, ta có thể dễ dàng thay đổi các lớp hoặc đối tượng được sử dụng bởi ExampleBlock
chỉ bằng cách chỉnh sửa tệp di.xml, mà không cần sửa đổi mã của ExampleBlock
hoặc các lớp khác phụ thuộc vào ExampleModel
.
Kết bài
Dependency Injection (DI) là một phương pháp quản lý các phụ thuộc trong các ứng dụng lớn, và nó được sử dụng rộng rãi và giảm thiểu phụ thuộc giữa các lớp, tăng tính linh hoạt và tái sử dụng của mã, cải thiện việc kiểm thử và bảo trì.
Cảm ơn các bạn đã dành thời gian xem bài viết này nhé! Có thắc mắc hay góp ý gì vui lòng comment vào bài viết mình sẽ giải đáp cho các bạn. Thân ái!