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
php artisan make:provider PaymentServiceProvider// 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
// 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 samaCatatan 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.