Pada artikel kali ini saya akan membahas tentang materi advance dari framework laravel yaitu Cara Menggunakan Service Container Di Laravel, Service container merupakan fitur unggulan yang di miliki oleh laravel , baiklah kita akan bahas lebih mendalam pada artikel ini.

Apa itu class dependency?

Class dependency dalam pemrograman adalah kondisi dimana kita membutuhkan class lain untuk membuat object dari sebuah class. Misalnya perhatikan class PaymentGateWay  dan OrderDetails berikut:

<?php

namespace App\Billing;


use Illuminate\Support\Str;


class PaymentGateWay 
{

    private $currency;
    private $discount;

    public function __construct($currency)
    {
        $this->currency = $currency;
        $this->discount = 0;
    }

    public function charge($amount)
    {
        return [
            'amount' => $amount - $this->discount,
            'confirmation_number' => Str::random(),
            'currency' =>  $this->currency,
            'discount'  => $this->discount
        ];
    }

    public function setDiscount($amount)
    {
        $this->discount = $amount;
    }
    
}
<?php

namespace App\Orders;

use App\Billing\PaymentGateWay;

class OrderDetails
{
    
    private $payment_gate_way;


    public function __construct(PaymentGateWay $payment_gate_way) 
    {
        $this->payment_gate_way = $payment_gate_way;
    }   


    public function all()
    {
        $this->payment_gate_way->setDiscount(1000);

        return [
            'name' => 'Bayu fajar sidik',
            'Address' => 'Cengkareng timur'
        ];
    }
}

bisa kita lihat ketergantungan (dependency) antara class PaymentGateWay  dan OrderDetails dimana jika ingin menjalankan class OrderDetails  maka kita juga harus menjalankan class PaymentGateWay  terlebih dahulu.  Jadi jika kita gunakan class tersebut dengan cara seperti ini maka akan terjadi error :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Billing\PaymentGateWay;
use App\Orders\OrderDetails;

class PayOrderController extends Controller
{
    public function store(OrderDetails $order_details, PaymentGateWay $payment_gate_way)
    {
        return [
            'order' => $order_details->all(),
            'charege' => $payment_gate_way->charge(30000)
        ];
        
    }
}

loh kenapa tetap error kan pada controller tersebut sudah di lakukan instace ? Betul harusnya setalah kita melakukan instance pada class PaymentGateWay  dan OrderDetails tak akan terjadi error.Tetapi coba teman-teman lihat baik-baik pada class PaymentGateWay pada bagian constructor nya :

public function __construct($currency)
    {
        $this->currency = $currency;
        $this->discount = 0;
    }

Pada method constructor tersebut kita juga melakukan set value untuk property $currency lalu bagaimana untuk melakukam set value nya ?  Ya bisa saja sih kita set saat kita lakukan instance nya di controller nya.  Tetapi bayangkan bagaimana jika banyak controller yang bergantung pada class tersebut ?  yupsssss heheh kita harus melakukan set value di semua controller yang ingin menginstace class PaymentGateWay.   Itu sangat tidak maintainable .

Lalu bagaimana caranya agar kita cukup 1 kali melakukan set value atau perubahan tetapi berdampak ke semua controller yang bergantung pada class PaymentGateWay ?
Jawabanya adalah serive container.

Kita akan buat Service Container nya pada file app/Providers/AppServiceProviders.php kita akan melakukan binding dengan menggunakan singleton pattern seperti berikut ini :

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Billing\PaymentGateWay;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(PaymentGateWay::class, function($app){
            return new PaymentGateWay('rupiah');
        });
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

nah setalh kita lakukan binding pada method register() maka kita telah bisa menggunakan class PaymentGateWay  dan OrderDetails tanpa mengalami error.

Oke seperti itu saja teman-taman untuk artikel Cara Menggunakan Service Container Di Laravel jika teman-teman pahami bahwa tujuan dari fitur Service Container ini untuk mengatasi dependency class yang banyak dengan cukup elegant dan sederhana agar code kita lebih efisien dan mudah di maintetance.