Trong các framework có Dependency Injection / IoC như Laravel hay Spring Framework, hai khái niệm Service ContainerService Provider thường đi cùng nhau nhưng vai trò hoàn toàn khác. Nhiều người mới học thường nhầm chúng là một.

Mình giải thích theo đúng bản chất để bạn dễ hình dung khi đọc code framework.


1. Service Container là gì

Service Container là nơi lưu trữ và tạo ra các object của ứng dụng.

Nó giống như một "nhà máy tạo object" + "kho chứa object".

Khi ứng dụng cần một class, container sẽ:

  1. Kiểm tra xem class đã được đăng ký chưa
  2. Nếu chưa thì tự tạo bằng Reflection
  3. Nếu có dependency thì tự động inject
  4. Trả instance cho nơi yêu cầu

Ví dụ trong Laravel:

$service = app()->make(OrderService::class);

hoặc

$service = $container->resolve(OrderService::class);

Quá trình xảy ra:

Controller
   ↓
Service Container
   ↓
OrderService
   ↓
Database / Logger / Mailer

Container sẽ:

new OrderService(new PaymentService(), new Logger())

tự động.

Ví dụ container đơn giản trong PHP

class Container {    
    protected $bindings = [];    
    public function bind($name, $class) {
        $this->bindings[$name] = $class;
    }    public function resolve($name) {
        $class = $this->bindings[$name];
        return new $class();
    }
}

2. Service Provider là gì

Service Provider là nơi đăng ký các service vào Service Container.

Nó giống như file cấu hình cho container.

Ví dụ:

class OrderServiceProvider {    
        public function register($container) {
        $container->bind(OrderService::class, function () {
            return new OrderService(new PaymentService());
        });
    }}

Khi application start:

App Boot
   ↓
Load Service Providers
   ↓
Register Services vào Container
   ↓
Application chạy

3. Ví dụ trong Laravel

Trong Laravel có file:

app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(
        PaymentInterface::class,
        StripePayment::class
    );
}

Ở đây:

$this->app = Service Container

Service Provider chỉ đăng ký.

Khi code gọi:

app(PaymentInterface::class);

container sẽ trả:

StripePayment instance

4. So sánh dễ hiểu

Thành phầnVai trò
Service Containernơi tạo và quản lý object
Service Providernơi đăng ký object vào container

Hiểu đơn giản:

Service Provider = nơi cấu hình
Service Container = nơi chạy thực tế

hoặc

Service Provider -> đăng ký service
Service Container -> tạo service

5. Luồng hoạt động

Toàn bộ flow:

Application start
      ↓
Load Service Providers
      ↓
Register services vào Container
      ↓
Application cần object
      ↓
Container resolve object
      ↓
Dependency Injection

6. Ví dụ thực tế

Giả sử hệ thống thanh toán.

Service:

PaymentInterface
StripePayment
PaypalPayment

Service Provider:

$this->app->bind(PaymentInterface::class, StripePayment::class);

Controller:

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

Container sẽ tự làm:

new OrderController(
    new StripePayment()
)

7. Tóm tắt cực dễ nhớ

Service Container = Object Factory
Service Provider = Service Registration

hoặc

Provider = khai báo
Container = thực thi