part_os
@part_os
Сложное в простом

Как связать сервис и интерфейс с несколькими реализациями?

Добрый вечер, подскажите как связать сервис с интерфейсом, и несколькими реализациями.
Например:
class SpiderService
{ 
 /**
     * SpiderService constructor.
     * @param AuctionRepositoryInterface $auctionRepository
     */
    public function __construct(AuctionRepositoryInterface $auctionRepository)
    {
        $this->auctionRepository = $auctionRepository;
    }
}

interface AuctionRepositoryInterface
{
    public function getActualDateAuctions();
}

class AuctionRepository implements AuctionRepositoryInterface
{
public function getActualDateAuctions()
    {
           //реализация
     }
}

class InMemoryAuctionRepository implements AuctionRepositoryInterface
{
 public function getActualDateAuctions()
    {
         //какая то реализация
    }
}


class SpiderServiceProvider extends ServiceProvider
{

    public function register()
    {
        $this->app->singleton('spider', 'App\Services\SpiderService');
    }
}

И как вызвать сервис с разной реализацией?
$service = app()->make(SpiderService::class);    // ???????
  • Вопрос задан
  • 248 просмотров
Решения вопроса 1
SerafimArts
@SerafimArts
Senior Notepad Reader
Это делается через контекстуальный биндинг (https://laravel.com/docs/5.7/container#contextual-...
// Когда SpiderService требует интерфейс AuctionRepositoryInterface, 
// то мы даём ему InMemoryAuctionRepository
$app->when(SpiderService::class)
   ->needs(AuctionRepositoryInterface::class)
   ->give(InMemoryAuctionRepository::class);

// Когда Someone требует интерфейс AuctionRepositoryInterface, 
// то мы даём ему AuctionRepository
$app->when(Someone::class)
   ->needs(AuctionRepositoryInterface::class)
   ->give(AuctionRepository::class);

// Во всех остальных случаях мы предоставляем AnotherRepository
$app->singleton(AuctionRepositoryInterface::class, AnotherRepository::class);


Будьте внимательны, т.к. контекстуальный биндинг не работает в случае внедрения через методы ($container->call), а только через конструктор.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Nc_Soft
https://laravel.com/docs/5.0/container#binding-int...
смотрите на $app->bind, как раз там привязка идет
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы