laravelcontainerarchitectureMahir3 mnt baca

Service Provider dan Container

Pahami jantung Laravel: binding di container, singleton, dan bedanya register() vs boot().

Container: kotak perkakas Laravel

Service container adalah tempat Laravel menyimpan cara membuat setiap object. Saat kamu type-hint Request $request di controller, container yang menginstansiasi dan menyuntikkannya. Ini disebut dependency injection, dan bikin kode gampang dites.

Binding: daftarkan cara membuat object

bash
php artisan make:provider PaymentServiceProvider
php
// app/Providers/PaymentServiceProvider.php
namespace App\Providers;

use App\Services\MidtransPayment;
use App\Contracts\PaymentGateway;
use Illuminate\Support\ServiceProvider;

class PaymentServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Setiap diminta, buat instance baru
        $this->app->bind(PaymentGateway::class, MidtransPayment::class);

        // Satu instance dipakai bersama (singleton)
        $this->app->singleton('laporan', function ($app) {
            return new \App\Services\LaporanService(
                $app->make(PaymentGateway::class)
            );
        });
    }

    public function boot(): void
    {
        // Dipanggil setelah semua provider ter-register.
        // Cocok untuk: Gate::define, view composer, macro.
    }
}

Daftarkan provider di bootstrap/app.php lewat ->withProviders([...]) kalau tidak auto-discovered.

register() vs boot()

Aturannya sederhana: register() hanya untuk binding ke container, jangan pakai service lain di sini karena belum tentu terdaftar. boot() dipanggil setelah SEMUA provider selesai register, jadi aman memakai service lain, mendaftarkan Gate, event listener, atau view composer.

Memakai binding

php
// Otomatis di-inject dimanapun di type-hint
public function bayar(PaymentGateway $gateway)
{
    $gateway->charge(100000); // instance MidtransPayment
}

// Atau resolve manual
$gateway = app(PaymentGateway::class);
$laporan = app('laporan'); // singleton: selalu instance yang sama

Catatan teknis: Bind interface ke implementasi (bukan class konkret ke class konkret). Dengan begitu, ganti payment gateway dari Midtrans ke Xendit cukup ubah SATU baris di provider, tanpa menyentuh controller manapun. Ini inti dari prinsip dependency inversion yang bikin codebase tahan lama.