Problem is that i don't know how to bind multitple implementations of one interface.
Example:
// One interface
interface SmsInterface {
...
}
// First implementation using SmsCoin
class SmscoinAPI implements SmsInterface {
...
}
// Second implementation using Fortumo
class FortumoAPI implements SmsInterface {
...
}
// Two controllers:
class SmsCoinController {
public function __construct(SmsInterface $sms) {
$this->sms = $sms
}
}
class FortumoController {
public function __construct(SmsInterface $sms) {
$this->sms = $sms
}
}
Question: How I can bind SmsInterface with implementation FortumoApi for FortumoController, and bind SmsInterface with implementation SmsCoinApi for SmsCoinController ?
I was using ServiceProvider for registering bindings, can I do it there ? If not where should bindings put?
EDIT:
I can't get answer anywhere, read many laravel books, everywhere is said to use multiple implementations, but nowhere is shown how to swap/switch those implementations.
If i have one interface and two implementations, how to bind and swap them in controller. Do i need to do that in that controller constructor method ? or in routes by checking controller's route or in filters.php ? or in Service provider ? and how to technically correclty write that code ?
This question took for me long time to solve it. After Laravel 5.0 is out i'm posting solution that i have found using Contextual binding
Consider this example, when one controller needs one interface with multiple implementations.
<?php
// We are creating one abstract controller with one logic
abstract class AbstractSearchController
{
protected $searchService;
public function __construct(SearchServiceInterface $searchService)
{
$this->searchService = $searchService;
}
public function getResult($keyword)
{
return $this->searchService->getItems($keyword);
}
}
// In routes.php file we can point url like: http://example.com/search/posts/?keyword=my-search-keyword to use
// something like this: Route::resource('search/posts', 'PostSearchController', ['only' => ['index']]);
class PostSearchController extends AbstractSearchController
{
// No code here as this controller only is needed so that we can point Specific implementation to it
}
// In routes.php file we can point url like: http://example.com/search/members/?keyword=my-search-keyword to use
// something like this: Route::resource('search/members', 'MemberSearchController', ['only' => ['index']]);
class MemberSearchController extends AbstractSearchController
{
//
}
// Our main interface that will have multiple implementations at same time
interface SearchServiceInterface
{
public function getItems($keyword);
}
// Our first implementation of interface
class MemberSearchRepo implements SearchServiceInterface
{
public function getItems($keyword)
{
// Get members by keyword
}
}
// Our second implementation of interface
class PostSearchRepo implements SearchServiceInterface
{
public function getItems($keyword)
{
// Get posts by keyword
}
}
// When PostsSearchController needs Search Logic point IoC to give our first implementation
$this->app->when('PostSearchController')->needs('SearchServiceInterface')->give('PostSearchRepo');
// When MemberSearchController needs Search Logic point IoC to give our seconds implementation
$this->app->when('MemberSearchController')->needs('SearchServiceInterface')->give('MemberSearchRepo');
I hope this extended example will help people to understand how to implement feature that I needed for Laravel 4.x with abillities that Laravel 5 provides
I've been trying to do the same, until I found it in the Laravel docs. It's called Contextual Binding, and the way in which you have to implement it is like this:
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;
$this->app->when(PhotoController::class)
->needs(Filesystem::class)
->give(function () {
return Storage::disk('local');
});
$this->app->when(VideoController::class)
->needs(Filesystem::class)
->give(function () {
return Storage::disk('s3');
});
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With