Quay lại

Resolving dependencies sử dụng service container trong Laravel Chuyên mục PHP và Laravel    2023-08-10    437 Lượt xem    31 Lượt thích    comment-3 Created with Sketch Beta. 0 Bình luận

Resolving dependencies sử dụng service container trong Laravel

Một trong những cách tiêu chuẩn để resolve dependencies (9giải quyết các phụ thuộc) trong Laravel là sử dụng service container. Về cơ bản, nếu bạn muốn thêm thứ gì đó có thể tráo đổi bất cứ lúc nào, bạn có thể thực hiện việc này bằng cách “biding” thứ đó vào service container.

Chẳng hạn, giả sử chúng ta đang sử dụng payment gateways (cổng thanh toán) vào ứng dụng của mình. Vì vậy, những gì chúng ta có thể làm là định nghĩa một interface có chứa các phương thức nhất định được gọi là payment và discount như sau.

namespace App\Payment\Contract;

interface PaymentInterface
{
    public function payment();

    public function discount();
}

Và bây giờ nếu chúng ta muốn sử dụng một phương thức payment  trong ứng dụng của mình, chúng ta có thể tạo một lớp cho phương thức payment đó sẽ triển khai App\Payment\Contract\PaymentInterface. Vì vậy, nếu chúng ta đang sử dụng phương thức payment  bằng thẻ tín dụng, chúng ta có thể tạo phương thức đó như này.

namespace App\Payment;

use App\Payment\Contract\PaymentInterface;

class CreditCard implements PaymentInterface
{
    public function payment()
    {
        // process payment
    }

    public function discount()
    {
        // process discount
    }
}

Binding interface vào class

Nếu chúng ta muốn thêm App\Payment\Contract\PaymentInterface vào bất kỳ controller constructor nào trong ứng dụng và mong muốn rằng nó sẽ được resolved thành App\Payment\CreditCard class mỗi lần, chúng ta cần liên kết nó vào service container bằng cách sử dụng bind hoặc phương pháp singleton như sau.

$this->app->bind(
    'App\Payment\Contract\PaymentInterface',
    'App\Payment\CreditCard'
);

Điều này sẽ cho container biết rằng nó sẽ thêm App\Payment\CreditCard khi một class cần triển khai App\Payment\Contract\PaymentInterface. Giờ đây, chúng ta có thể type-hint interface App\Payment\Contract\PaymentInterface trong constructor hoặc bất kỳ vị trí nào khác nơi các dependencies injected bởi service container và nó sẽ được resolved thành App\Payment\CreditCard như này.

use App\Payment\Contract\PaymentInterface;

public function __construct(PaymentInterface $payment)
{
    $this->payment = $payment;
}

Resolve dependencies conditionally/contextually

Hãy tưởng tượng bây giờ chúng ta có một phương thức thanh toán khác gọi là App\Payment\Stripe cũng đang triển khai interface App\Payment\Contract\PaymentInterface và bạn muốn sử dụng cả hai phương thức thanh toán nhưng trong các controllers khác nhau. Chẳng hạn, bạn muốn sử dụng lớp CreditCard trong controller AccountRenewalController và class Stripe trong controller BuyController, bạn sẽ làm điều đó như thế nào?

Um thì, câu trả lời là, chúng ta sẽ cần ràng buộc cả hai điều kiện dựa trên nơi chúng được gọi. Điều này có thể đạt được bằng cách sử dụng fluent interface , nơi chúng ta có thể xác định cách resolved các dependencies trong các tình huống nhất định.

Vì vậy, nếu chúng ta muốn resolved App\Payment\Contract\PaymentInterface thành App\Payment\CreditCard , chúng ta có thể xác định ràng buộc như sau.

use App\Http\Controllers\AccountRenewalController;
use App\Payment\Contract\PaymentInterface;
use App\Payment\CreditCard;

$this->app->when(AccountRenewalController::class)
          ->needs(PaymentInterface::class)
          ->give(CreditCard::class);

Và nếu chúng ta muốn resolved App\Payment\Contract\PaymentInterface thành App\Payment\Stripe trong controller BuyController, chúng ta có thể xác định ràng buộc như sau.

use App\Http\Controllers\PurchaseController;
use App\Payment\Contract\PaymentInterface;
use App\Payment\Stripe;

$this->app->when(PurchaseController::class)
          ->needs(PaymentInterface::class)
          ->give(function () {
              return Stripe('sid', 'token')
          });

Như bạn có thể thấy, bạn có thể tạo các ngữ cảnh dựa trên nơi mà các dependencies  đang được sử dụng và return/resolve classes các class hoặc các class instances tương ứng.

 

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday