Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

underser's avatar

Service Container set Interface implementation just for one class method

I have \App\Repository\ProductRepositoryInterface and a class that implements that interface \App\Repository\ProductRepository.

If I create an invocable controller and request ProductRepositoryInterface like this:

    /**
     * Handle the incoming request.
     */
    public function __invoke(
		Request $request, 
	    ProductRepositoryInterface $productRepository
    ) {
    }

Is there a way I tell Laravel service container implementation for ProductRepositoryInterface just for that concrete controller?

Please note that

// To global as it sets implementation for all classes - I need only for one controller's method
$this->app->bind(ProductRepositoryInterface::class, ProductRepository::class, true);

or

// Works only when I inject ProductRepositoryInterface into __construct 
        $this->app->when(Controller::class)
            ->needs(ProductRepositoryInterface::class)
            ->give(ProductRepository::class);

Is there a way to achieve the above? Thanks in advance!

0 likes
2 replies
underser's avatar

So far found a pretty weird way to archive the above, is by using bindMethod, but it turns out that the controller itself needs to be called in a non-standard manner.

AppServiceProvider

        $this->app->bindMethod([Some::class, '__invoke'], function (string $class, Container $container) {
            /** @var Some $controller */
            $controller = $container->make($class);

            return $controller(
                $container->make(Request::class),
                $container->make(ProductRepository::class),
            );
        });

And then in order to make the above to be called you need to use a call method on a Service Container:

Route::get('test', function (Illuminate\Contracts\Container\Container $container) {
    return $container->call([\App\Http\Controllers\Some::class, '__invoke']);
});

Please or to participate in this conversation.