A (simplified) example:
use App\ValueObjects\PhoneNumber;
interface SmsProvider
{
public function sendSms(PhoneNumber $from, PhoneNumber $to, string $message);
}
use Vonage\Client;
use Vonage\SMS\Message\SMS;
class VonageSmsProvider implements SmsProvider
{
protected $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function sendSms(PhoneNumber $from, PhoneNumber $to, string $message)
{
$text = new SMS($to, $from, $message);
$response = $this->client->sms()->send($text)->current();
return $response->getStatus() == 0;
}
}
You can use the container to build the VonageSmsProvider class:
$this->app->singleton(VonageSmsProvider::class, function () {
$credentials = new Basic(
$this->app['config']['services.vonage.api_key'],
$this->app['config']['services.vonage.api_secret'],
);
$client = new Client($credentials);
return new VonageSmsProvider($client);
});
And then also specify which provider should implement the interface in your application:
$this->app->singleton(SmsProvider::class, VonageSmsProvider::class);
So when you type-hint SmsProvider, Laravel will work out you want an instance of VonageSmsProvider, and build an instance of that class.