Pete McFarlane
Pete McFarlane

Reputation: 441

Automatic Binding Resolution with Illuminate/Container outside of Laravel

I'm trying to introduce some Illuminate components to rescue a legacy app, namely the Container, Events and Router. I can't get past a BindingResolutionException when trying to bind a concrete class to an interface.

index.php

<?php

require __DIR__ . '/vendor/autoload.php';

$app = new Illuminate\Container\Container;

$app->bind('dispatcher', function () {
    return new Illuminate\Events\Dispatcher;
});

$app->bind('router', function ($app) {
    return new Illuminate\Routing\Router($app['dispatcher']);
});

// This is the interface I'm trying to bind
$app->bind('App\Logable', function () {
    return new App\Logger();
});

$router = $app['router'];

// This is where I'm trying to use automatic binding resolution
$router->get('/', function (App\Logable $logger) {
    return $logger->log();
});

$request = Illuminate\Http\Request::createFromGlobals();
$response = $router->dispatch($request);
$response->send();

src/Logable.php

<?php

namespace App;

interface Logable
{
    public function log();
}

src/Logger.php

<?php

namespace App;

class Logger implements Logable
{
    public function log()
    {
        var_dump($this);
    }
}

Does anyone have any ideas? I'm not sure if I need to register as a service provider, or if I need to use the Illuminate\Application\Foundation for that? If so, is that the only way?

Thanks in advance

Upvotes: 1

Views: 645

Answers (1)

Pete McFarlane
Pete McFarlane

Reputation: 441

I realised I was instantiating multiple containers instead of passing the one I had first created (by looking at the object IDs). My solution was to pass the container to the router when instantiating that:

$app->bind('router', function ($app) {
    return new Illuminate\Routing\Router($app['dispatcher'], $app);
});

Then everything worked as expected.

Upvotes: 2

Related Questions