29/09/2018, 11:43

Service Container

Khi làm việc với Laravel thì không thể không nhắc đến Service Container một khái niệm cốt lõi trong Laravel mà bạn ko thể bỏ qua. Service Container thực sự là trái tim của framework này. Hôm nay tôi sẽ hướng dẫn các bạn cách mà service container hoạt động như thế nào. Khi bạn hiểu được nó thì bạn sẽ tự tin hơn khi làm việc với Laravel.

Khi làm việc với Laravel thì không thể không nhắc đến Service Container một khái niệm cốt lõi trong Laravel mà bạn ko thể bỏ qua. Service Container thực sự là trái tim của framework này. Hôm nay tôi sẽ hướng dẫn các bạn cách mà service container hoạt động như thế nào. Khi bạn hiểu được nó thì bạn sẽ tự tin hơn khi làm việc với Laravel.

Nguyên văn của trang chủ laravel:

"The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods."  Từng đó thôi có lẽ các bạn sẽ không hiểu hết về công cụ mạnh mẽ này. 

trước hết chúng ta sẽ nhắc đến 2 khái niệm mà liên quan đến Service Container.

Dependency Injection:

Nếu một Class A hoạt động phụ thuộc vào một vài Class B, thì thay vì khởi tạo các instance của Class B bên trong Class A, ta sẽ inject những instance của class B vào thông qua constructor hay setter. Instance của Class B mà Class A cần để hoạt động đó được gọi là dependency. 

ví dụ: 

<?php

class A {
	public function getName(){
		return 'Hello World';
	}
}

//ta sẽ khởi tạo instance của class A bên trong class B
class B
{
	protected $a;

	public function __construct(){
		$this->a = new A;
	}

	public function getName()
	{
		return $this->a->getName();
	}
}

$b = new B;

echo $b->getName(); // Hello world


// Dependency Injection: thay vì khởi tạo trược tiếp class A bên trong class C thì tao sẽ truyển thể hiện của class A vào class C thông qua constructor hoặc setter
// trong trường hợp dưới là constructor
class C {

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

	public function getName()
	{
		return $this->a->getName();
	}
}

$a = new A;
$c = new C($a);

Inversion of Control(IoC):

IoC là một kỹ thuật trong lập trình làm "đảo ngược" flow của những xử lý truyền thống. Bình thường thì đoạn xử lý logic của ta sẽ gọi đến những class, library mà nó cần dùng, thế nhưng, với IoC thì ta sẽ gửi cho những đoạn xử lý logic đó những thứ mà nó cần. Với IoC thì các sự phụ thuộc sẽ được ghép vào các đối tượng tương ứng tại thời điểm run time thay vì compile time.

<?php

// đăng kí với Container
App::bind('C', function($app){
	return new C(new A, new B);
});

// với IoC Container khi lấy ra 
$c = App::make('C');

// theo cách thông thường 
$c = new C(new A, new B);

Nhìn ở ví dụ trên thì bạn có thể nghĩ rằng cách 1 sẽ dài dòng hơn đúng không ? Nhưng bạn hãy suy nghĩ lại với trường hợp C được khởi tạo theo cách thông thường mà việc khởi tạo phức tạp hơn tốn nhiều công sức hơn, và bạn lại phải khởi tạo C ở nhiều nơi. Như vậy đoạn code để khởi tạo C sẽ lặp đi lặp lại nhiều lần. Đó là lý do tại sao IoC container lại có ý nghĩa vì logic khởi tạo C chỉ được gói gọn tạo một nơi và sau đó ta chỉ việc gọi nó. Như trong ví dụ trên thì cụ thể là $c = App::make('C') đơn giản vậy thôi.

Đến đây các bạn đã hiểu về 2 khái niêm trên. Tiếp theo mình muốn giới thiệu các tính năng mạnh mẽ mà Service Container (IoC) mang lại cho các bạn.
 

Binding:

Hầu như tất cả các Service Container binding của bạn sẽ được đăng ký trong các Service Provider, vì vậy hầu hết các ví dụ này sẽ chứng minh bằng cách sử dụng Container trong Service Provider

Simple Bindings: 

Trong các serivce provider, bạn luôn có quyền truy cập vào container thông qua thuộc tính $this->app. Chúng ta có thể đăng ký một binding bằng cách sử dụng phương thức bind, truyền tên lớp hoặc tên giao diện mà chúng ta muốn đăng ký cùng với một Closure để trả về một cá thể của lớp:

$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});




 

Hoa Nguyen viết 2 tuần trước

Binding A Singleton
 

$this->app->singleton('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); });

 

Binding Instance
 

$api = new HelpSpot\API(new HttpClient);

$this->app->instance('HelpSpot\API', $api);


Binding Interfaces To Implementations
 

$this->app->bind( 'App\Contracts\EventPusher', 'App\Services\RedisEventPusher' );

 

Contextual Binding

Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, two controllers may depend on different implementations of the Illuminate\Contracts\Filesystem\Filesystem contract. Laravel provides a simple, fluent interface for defining this behavior:

use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;

$this->app->when(PhotoController::class)
          ->needs(Filesystem::class)
          ->give(function () {
              return Storage::disk('local');
          });

$this->app->when([VideoController::class, UploadController::class])
          ->needs(Filesystem::class)
          ->give(function () {
              return Storage::disk('s3');
          });
Bài liên quan

Service Container là gì?

Bạn đang học về Laravel Framwork? Bạn đã biết sử dụng cơ bản về Laravel Framework? Bạn đã từng đọc lướt qua về khái niệm Service Container trong Documentation của Laravel. Vậy bạn đã thực sự hiểu nó? Học cách xây dựng một ứng dụng Laravel không chỉ là cách học các lớp và các thành phần khác ...

Hoàng Hải Đăng viết 3 ngày trước

Facades và mối quan hệ giữa Facades với Service Container trong Laravel

Tìm hiểu về Facade trong Laravel Static method Các thuộc tính, phương thức trong lớp khai báo với từ khóa static là một đặc tính hữu dụng trong PHP. Về cơ bản, phương thức / thuộc tính tĩnh (static) thì nó có thể truy cập trực tiếp mà không phải tạo đối tượng của lớp. Ví dụ về static ...

Tạ Quốc Bảo viết 3 ngày trước

Service Container

Khi làm việc với Laravel thì không thể không nhắc đến Service Container một khái niệm cốt lõi trong Laravel mà bạn ko thể bỏ qua. Service Container thực sự là trái tim của framework này. Hôm nay tôi sẽ hướng dẫn các bạn cách mà service container hoạt động như thế nào. Khi bạn hiểu được nó thì bạn sẽ ...

Hoa Nguyen viết 3 tuần trước

Laravel: Tìm hiểu về Service Container

Laravel service container là một công cụ rất mạnh trong việc quản lý các class dependencies và thực hiện xử lý dependency injection. Dependency injection là một cụm từ thể hiện có nghĩa là: các dependencies của class được "injected" vào trong class thông qua hàm khởi tạo hoặc trong một số trường ...

Tạ Quốc Bảo viết 18:23 ngày 12/08/2018

Tìm hiểu về Service Container trong Laravel

Xin chào các anh em, hôm qua mình vừa mới phát hiện ra một điều rất hay trong Laravel mà hôm nay mình muốn lên chia sẻ ngay cho anh em. Thế nhé, mình sẽ tiếp tục series Laravel và những điều thú vị thì hôm nay mình sẽ chia sẻ cho anh em về Service Container trong Laravel, nó được dùng khắp nơi ...

Tạ Quốc Bảo viết 18:18 ngày 12/08/2018
+3