Home > Software design >  Service Provider not Resolving a registration: Target [App\\Services\\Payment\\Contracts\\Pa
Service Provider not Resolving a registration: Target [App\\Services\\Payment\\Contracts\\Pa

Time:10-05

I have an interface that I wish to resolve on controllers. On registration inside a service provider, I am binding a class to the Service on condition.

Here is my service interface and two classes.

PaymentService::class


namespace App\Services\Payment\Contracts;

use App\Models\ParkingBill;

interface PaymentService
{
    
    public function request(ParkingBill $parkingBill, string $client): bool;

    public function confirm(ParkingBill $parkingBill, string $client): bool;
}

MpesaPaymentService::class

namespace App\Services\Payment;

use App\Models\ParkingBill;
use App\Models\PaymentMethod;
use App\Services\Payment\Contracts\PaymentService;

class MPesaPaymentService implements PaymentService
{

    private PaymentMethod $paymentMethod;

    public function __construct(PaymentMethod $paymentMethod)
    {
        $this->paymentMethod = $paymentMethod;
    }

    public function request(ParkingBill $parkingBill, string $client): bool
    {
        return true;
    }

    public function confirm(ParkingBill $parkingBill, string $client): bool
    {
        return false;
    }
}

AirtelPaymentService::class

namespace App\Services\Payment;

use App\Models\ParkingBill;
use App\Models\PaymentMethod;
use App\Services\Payment\Contracts\PaymentService;

class AirtelMoneyPaymentService implements PaymentService
{

    private PaymentMethod $paymentMethod;

    public function __construct(PaymentMethod $paymentMethod)
    {
        $this->paymentMethod = $paymentMethod;
    }

    public function request(ParkingBill $parkingBill, string $client): bool
    {
        return true;
    }

    public function confirm(ParkingBill $parkingBill, string $client): bool
    {
        return false;
    }
}

Here is the register method of PaymentServiceProvider where am binding the class

       $this->app->bind(PaymentService::class, function ($app) {

           PaymentMethod::query()
                ->where('id', request()->input('payment_method'))
                ->first();
            
            if ($paymentMethod->type == 'mpesa') {
                return new MPesaPaymentService($paymentMethod);
            } elseif ($paymentMethod->type == 'airtel') {
                return new AirtelMoneyPaymentService($paymentMethod);
            } else {
                return null;
            }

        });

I have also added the provider to the list of providers inside the app.php config file.


'providers' => [
    //...
   
        \App\Providers\PaymentServiceProvider::class,

    //...
]

Then this is where am trying to type hint it inside the controller method and access it inside the controller.

public function store(PaymentService $paymentService, Request $request, ParkingBill $parkingBill){

   //...

    return $paymentService->request($parkingBill, $request->payment_client);

}

I expect to get true or false based on the payment method I submit but am actually getting an exception.

Here is the exception

{
    "message": "Target [App\\Services\\Payment\\Contracts\\PaymentService] is not instantiable.",
    "exception": "Illuminate\\Contracts\\Container\\BindingResolutionException",
    "file": "C:\\wamp64\\www\\my-valet\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
    "line": 1087,
    "trace": [...]

I have tried to remove the conditional binding but it is still not behaving, what could I be doing wrong?

I am using php V8.1.0 and Laravel V9

CodePudding user response:

PaymentMethod query

$paymentMethod = PaymentMethod::find(request()->input('payment_method'));

Or,

$paymentMethod = PaymentMethod::query()
                ->where('id', request()->input('payment_method'))
                ->first();
  • Related