Laravel: Différence App::bind et App::singleton
Je suis un peu confuse sur toutes les belles choses laravel a à offrir en termes de conteneur IOC et des façades. Depuis que je ne suis pas un programmeur expérimenté, il devient accablant pour apprendre.
Je me demandais, quelle est la différence entre ces deux exemples:
-
Une façade 'Foo' et inscrit dans le conteneur via
App::bind()
-
Une façade 'Foo' et inscrit dans le conteneur via
App::singleton()
Dans mon meilleur compréhension Foo::method()
va être réécrit comme $app->make['foo']->method()
ainsi, dans le premier exemple de plusieurs instances de la Foo
classe sera créée et dans le deuxième exemple, puisqu'il est lié par l'intermédiaire d'un App::singleton()
, la même instance de Foo
sera retourné à chaque fois une Méthode sur cet objet est appelé.
Je suis désolé si la réponse à cette question est évidente, mais je ne trouve pas de confirmation sur cette question et de nulle part, c'est clairement expliqué.
- Ne pas présenter des excuses pour ne pas comprendre quelque chose. Croyez-moi, vous n'êtes pas seul!
Vous devez vous connecter pour publier un commentaire.
C'est exactement comme ça.
Très simple, la preuve est à l'essai de la bevahior. Depuis l'Application Laravel étend simplement
Illuminate\Container\Container
, je vais utiliser le conteneur (dans mon cas, j'ai même ajouté le conteneur en tant que dépendance de mon compositeur.json) pour tester.Le résultat est comme prévu:
Bind: test vs. test2
Singleton: test2 vs. test2
Peut-être un sale la preuve, mais en effet c'est l'un.
Toute la magie réside dans le
Container::make
méthode.Si la liaison est enregistré comme partagée (ce qui signifie que singleton), l'instance de classe est retourné, sinon une nouvelle instance à chaque fois.
Source: https://github.com/laravel/framework/blob/4.2/src/Illuminate/Container/Container.php#L442
BTW,
Container::singleton
est le même queContainer::bind
avec le troisième paramètre est défini sur true.app()->instance(Address::class, $address);
après ça, vous aurez de cette instance, peu importe si c'étaitbind
ousingleton
au début. Mais seulement Jusqu'à ce que vous décidez pas à utiliserapp()->makeWith(...)
en sorcière cas, vous devrez faire un objet pour vous, peu importe si c'étaitbind
ousingleton
ou même affecté en tant queinstance
... il y a des conditions d'après les conditions... j'aime Laravel.Façades faire un travail en tant que singleton, même si le sous-jacent de liaison n'est pas un singleton.
Disons que vous avez:
et:
Puis cela va créer 2 instances de
FooConcrete
, comme d'habitude:Mais cela va créer une seule instance de
FooConcrete
et le réutiliser:C'est parce que
resolveFacadeInstance()
magasins de l'résolu instances.Il y a cependant une exception. La plupart du temps, la définition de
getFacadeAccessor()
renvoie une chaîne, comme indiqué ci-dessus, mais il peut également renvoyer un objet. Exemple de laSchema
Façade:Dans un tel cas,
resolveFacadeInstance()
ne pas stocker l'instance.Donc si
getFacadeAccessor()
retourne une nouvelle instance, chaque appel à la Façade crée une nouvelle instance ainsi.clearResolvedInstances()
méthode pour supprimer la stockées cas, donc, si vous souhaitez obtenir un nouvel objet à chaque appel sur la Façade vous pouvez utiliser cette méthode dans l'getFacadeAccessor()
droit de la méthode avant de retourner le béton de la chaîne.clearResolvedInstance()
(pas de "s") pour effacer uniquement ce dont vous avez besoin, pas du tout. Néanmoins, vous seriez mieux de tout simplement retourner une instance.Mais j'ai lu quelque part que Laravel traite classes via des façades toujours comme des singletons?
Ainsi, j'ai rencontré ce problème:
J'ai un démo classe normalement lié par
Une orig une façade
La classe elle-même ressemble à ceci
Vous m'avez dit que si je voulais utiliser une façade sur cette classe, instancier un objet de la classe, puis d'appeler la méthode sur cet objet.
Bout à bout j'ai testé et trouvé cela très étrange (au moins pour moi) comportement:
Si je ne
et
Je ne devrais pas être en mesure d'utiliser Demo::getVals() pour récupérer les valeurs que je viens de créer, devrais-je? Car à chaque fois qu'une façade méthode est utilisée un nouvel objet sera instancié et comment peut-on l'objet de récupérer les propriétés d'un autre objet? Il devrait y avoir trois différentes instances encore, mais je suis en mesure de récupérer les propriétés de ceux d'autres instances...