1

J'ai une classe qui agit comme un stockage (élément add/get). J'essaie de le lier en tant que singleton dans un fournisseur de service, et de le résoudre dans la méthode de démarrage d'un autre.Laravel 5 Résolution des dépendances dans ServiceProvider

Le code est modifié pour plus de simplicité.

app/fournisseurs/BindingProvider.php

<?php namespace App\Providers; 

use Illuminate\Support\Facades\Facade; 
use Illuminate\Support\ServiceProvider as ServiceProvider; 

class MyBindingFacade extends Facade { 
    public static function getFacadeAccessor() { 
     return 'my.binding'; 
    } 
} 

class MyBinding { 

    protected $items = []; 

    public function add($name, $item) { 
     $this->items[$name] = $item; 
    } 
    public function get($name) { 
     return $this->items[$name]; 
    } 
    public function getAll() { 
     return $this->items; 
    } 

} 

class BindingProvider extends ServiceProvider { 

    public function register() { 
     $this->app->singleton('my.binding', function($app) { 
      return $app->make('App\Providers\MyBinding'); 
     }); 
    } 

    public function provides() { 
     return [ 
      'my.binding', 
     ]; 
    } 
} 

app/Fournisseurs/ResolvingProvider.php

<?php namespace App\Providers; 

use Illuminate\Support\ServiceProvider as ServiceProvider; 
use App\Providers\MyBinding; 

class ResolvingProvider extends ServiceProvider { 

    public function boot(MyBinding $binding) { 
     $binding->add('foo', 'bar'); 

     // $manual = $this->app->make('my.binding'); 
     // $manual->add('foo', 'bar'); 
    } 

    public function register() {} 

} 

app/Http/Contrôleurs/WelcomeController.php

<?php 
namespace App\Http\Controllers; 

use App\Providers\MyBindingFacade; 

class WelcomeController extends Controller { 

    public function index() 
    { 
     dd(MyBindingFacade::getAll()); // debug items 
    } 
} 

Lorsque j'essaie de déboguer l'état MyBinding dans mon WelcomeController, je reçois un tableau d'éléments vide. Cependant, si je décommente $manual partie de mon ResolvingProvider, il retourne un tableau contenant 'foo' => 'bar'. Cela signifie-t-il que la résolution de l'IoC est rompue dans la méthode ServiceProvider::boot() ou est-ce que j'utilise mal la fonctionnalité de Laravel?

Version Laravel: 5.0.28

MISE À JOUR: exemple de code ajouté à partir WelcomeController.

Répondre

2

Avec ceci:

$this->app->singleton('my.binding', function($app) { 
    return $app->make('App\Providers\MyBinding'); 
}); 

Vous vous dites: my.binding est un singleton et décide d'une instance de App\Providers\MyBinding.

Cela ne signifie pas que App\Providers\MyBinding est également enregistré en tant que singleton. Ce que vous devez faire est plutôt ceci:

$this->app->singleton('App\Providers\MyBinding'); 

$this->app->bind('my.binding', function($app) { 
    return $app->make('App\Providers\MyBinding'); 
}); 

Parce que l'utilisation de liaison Façade $app->make() vous devriez obtenir la même instance que vous avez enregistré avec $this->app->singleton() juste au-dessus.

+0

On dirait que je demandais à IoC pour une sorte de magie noire. Maintenant je comprends. Merci, Lukas! – fakemeta

0

Dans le premier exemple, vous n'utilisez pas la façade, vous devez utiliser:

use App\Providers\MyBindingFacade as MyBinding; 

qui à fait appel à l'aide faire « my.binding ».

+0

MyBindingFacade ne doit-il pas toujours renvoyer une instance derrière my.binding? Pourriez-vous fournir plus d'informations sur votre solution? – fakemeta

+0

J'ai également mis à jour ma question avec l'exemple de code de mon 'WelcomeController' où' MyBindingFacade' est utilisé. – fakemeta