Tutorial Laravel #25: Laravel Service Container dan Dependency Injection

1. Apa itu Service Container?

Service Container adalah IoC (Inversion of Control) container di Laravel - sebuah "kotak ajaib" yang tahu cara membuat object dan mengelola dependency antar class. Hampir semua fitur Laravel berjalan di atas service container.

Konsep dasarnya sederhana: daripada class membuat dependency-nya sendiri, dependency disuntikkan dari luar.

2. Dependency Injection (DI)

// Tanpa DI - buruk karena sulit ditest dan tightly coupled
class ArtikelController extends Controller
{
    public function index()
    {
        $service = new ArtikelService(new ArtikelRepository(new DB()));
        return $service->getAll();
    }
}

// Dengan DI - lebih baik, Laravel otomatis inject
class ArtikelController extends Controller
{
    // Laravel otomatis resolve dan inject ArtikelService
    public function __construct(private ArtikelService $service) {}

    public function index()
    {
        return $this->service->getAll();
    }
}

3. Binding ke Container

<?php
// app/Providers/AppServiceProvider.php
namespace AppProviders;

use IlluminateSupportServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Bind interface ke implementasi konkret
        $this->app->bind(
            AppContractsArtikelRepositoryInterface::class,
            AppRepositoriesEloquentArtikelRepository::class
        );

        // Singleton - hanya dibuat satu kali, instance yang sama dipakai terus
        $this->app->singleton(
            AppServicesCacheService::class,
            fn($app) => new AppServicesCacheService(config('cache.ttl'))
        );
    }
}

4. Membuat Service Class

<?php
// app/Services/ArtikelService.php
namespace AppServices;

use AppModelsArtikel;
use IlluminatePaginationLengthAwarePaginator;

class ArtikelService
{
    public function getPublished(int $perPage = 10): LengthAwarePaginator
    {
        return Artikel::with(['user', 'kategori', 'tags'])
                      ->where('status', 'published')
                      ->latest()
                      ->paginate($perPage);
    }

    public function create(array $data, int $userId): Artikel
    {
        return Artikel::create(array_merge($data, ['user_id' => $userId]));
    }

    public function update(Artikel $artikel, array $data): bool
    {
        return $artikel->update($data);
    }
}
<?php
// Controller - inject service via constructor
namespace AppHttpControllers;

use AppServicesArtikelService;

class ArtikelController extends Controller
{
    public function __construct(private ArtikelService $artikelService) {}

    public function index()
    {
        $artikels = $this->artikelService->getPublished(12);
        return view('artikel.index', compact('artikels'));
    }
}

5. Service Provider

php artisan make:provider PaymentServiceProvider
<?php
// app/Providers/PaymentServiceProvider.php
namespace AppProviders;

use IlluminateSupportServiceProvider;
use AppServicesPaymentGateway;
use AppServicesMidtransGateway;

class PaymentServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(PaymentGateway::class, function () {
            return new MidtransGateway(
                config('payment.midtrans.server_key'),
                config('payment.midtrans.is_production')
            );
        });
    }
}

6. Facades

Facade adalah cara mengakses service dari container dengan sintaks statis yang nyaman:

// Pakai facade
Cache::put('key', 'value', 3600);
$val = Cache::get('key');

Storage::put('file.txt', 'konten');
Log::info('Something happened');

// Di balik layar facade memanggil method dari object yang di-resolve container

7. Ringkasan

  • Service Container mengelola pembuatan object dan dependency antar class
  • Dependency Injection membuat kode lebih modular, mudah ditest, dan tidak tightly coupled
  • Bind interface ke implementasi di AppServiceProvider
  • Service class memisahkan business logic dari controller

Tutorial berikutnya membahas event, listener, dan observer di Laravel.


ariq fadhil

Im Ariq Tech, a Top Rated Fullstack Developer with 5+ years of experience, delivering high-quality solutions across 50+ projects.