Laravel différence "entre app - > bind` et "app->singleton"?

j'ai essayé de comprendre quelle est la différence entre app->bind et app->singleton sont lors de la mise en place d'un prestataire de services à Laravel. J'étais sous l'impression que si j'enregistre un singleton il serait de retour la même instance de l'objet à chaque fois qu'il a été appelé vs bind qui serait une nouvelle instance.

Ici est simple exemple:

Façade:

use IlluminateSupportFacadesFacade;

class DataFacade extends Facade
{
    protected static function getFacadeAccessor() { 
        return 'Data';
    }
}

fournisseur de services:

use IlluminateSupportServiceProvider;

class DataServiceProvider extends ServiceProvider
{
    public function register() {
        $this->app->singleton('Data', function() {
            return new Data;
        });
    }
}

Classe:

class Data
{
    public $data = [];

    public function get($key)
    {
        return isset($this->data[$key]) ? $this->data[$key] : null;
    }

    public function set($key, $val)
    {
        $this->data[$key] = $val;
    }
}

Si nous faisons quelque chose comme:

$instance = App::make('Data');
$instance->set('foo', 'foo');

$instance2 = App::make('Data');

echo $instance->get('foo');
echo $instance2->get('foo');

Et exécuter que nous allons voir le comportement approprié entre bind et singletonfoo être imprimés Une fois puis deux fois respectivement. Cependant, si nous le faisons passer à travers la façade comme ceci:

Data::set('test', 'test');
Data::set('cheese', 'cheese');

Quand c'est un singleton, je m'attends à la fois test et cheese et si c'est un bind Je ne suis pas sûr de ce que je m'attendrais à être disponible via la façade, mais il semble qu'il n'y a pas de différence.

c'est la façade qui traite tout comme un <!--7?

9
demandé sur Rob 2014-09-12 01:56:19

1 réponses

votre question est un peu confuse et n'a pas toute l'information pour répondre, mais c'est un sujet confus, alors ne vous sentez pas mal. Voici un résumé qui peut vous aider à mieux comprendre, et poser la question que vous vouliez poser (aussi, je suis newish à Laravel, donc je peux être hors de la base avec ceux-ci)

  1. make méthode est utilisée pour instancier des objets. Quand vous dites App::make('Data') vous dites à Laravel d'instancier un objet de la classe Data.

  2. il y a une mise en garde au numéro 1. Si vous appelez makeet ont déjà lié la chaîne Data pour quelque chose dans le conteneur de service, Laravel retournera le service à la place. Cela peut signifier que Laravel instancie un nouvel objet de service, ou que Laravel retourne un singleton de service

  3. que Laravel renvoie ou non un singleton ou une instance pour un service dépend de comment était le service lié

  4. make méthode de ne pas lier quelque chose

  5. vous liez des services avec l'objet d'application bind méthode, définie sur la classe conteneur avec le prototype de méthode suivant public function bind($abstract, $concrete = null, $shared = false)

  6. Voir la troisième $shared paramètre? Si c'est vrai, votre service vous ramènera un singleton. Si c'est faux, votre service retournera les instances.

  7. le l'objet application singleton méthode est une méthode pour la liaison des services

Re: n ° 7, voici la définition de l' singleton

#File: vendor/laravel/framework/src/Illuminate/Container/Container.php
public function singleton($abstract, $concrete = null)
{
    $this->bind($abstract, $concrete, true);
}

dans les exemples ci-dessus, vous liez le service Data dans le récipient. L'utilisation d'un nom de service de cas principal va causer des problèmes -- data serait un meilleur choix. Si votre register méthode n'est pas appelée pour une raison quelconque, make toujours instancier un objet de votre classe Data

en ce qui concerne votre façade -- une façade est une couche supplémentaire d'instance/singleton-ness. Voici la méthode où la façade de la classe utilise la chaîne de getFacadeAccessor pour renvoyer un objet d'un appel statique

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) return $name;

    if (isset(static::$resolvedInstance[$name]))
    {
        return static::$resolvedInstance[$name];
    }

    return static::$resolvedInstance[$name] = static::$app[$name];
}

ainsi, une façade utilise $app[$name]; pour prendre un service dans le container. C'est ArrayAccess, donc si on regarde la définition de offsetGet

public function offsetGet($key)
{
    return $this->make($key);
}

nous voyons ArrayAccess encapsule un appel à make. Cela signifie que si vous n'avez pas lié service, façade d'accès va instancier un objet. Si vous avez le service lié comme un service unique / partagé, l'accès de façade retournera ce singleton. Si vous avez le service lié comme non un service unique / partagé, facade access instanciera un nouvel objet.

cependant, la façade elle-même va stocker tout objet qu'elle instancie à l'intérieur static::$resolvedInstance, et les appels futurs à la façade retourneront cette même instance. Cela signifie que L'accès à la façade introduit un second singleton application. Un service relié comme un singleton sera stocké sur l'objet d'application, un service auquel on accède via une façade sera stocké comme un singleton sur le Facade classe.

22
répondu Alan Storm 2014-11-08 20:04:06