65 votes

Quel est le concept de conteneur de service dans Laravel ?

Je commence à m'intéresser à Laravel mais je ne comprends pas le concept de conteneur de service.

Comment cela fonctionne-t-il et que doivent savoir les développeurs pour utiliser pleinement ce concept dans Laravel ?

96voto

Moppo Points 4897

Le site Conteneur de service dans Laravel est un conteneur d'injection de dépendances et un registre pour l'application.

Les avantages de l'utilisation d'un conteneur de service par rapport à la création manuelle de vos objets sont les suivants :

Possibilité de gérer les dépendances de classe lors de la création d'un objet

Vous définissez la manière dont un objet doit être créé en un point de l'application (la liaison) et chaque fois que vous avez besoin de créer une nouvelle instance, il suffit de le demander au conteneur de services, qui la créera pour vous, avec les dépendances requises.

Par exemple, au lieu de créer des objets manuellement avec la fonction new mot-clé :

//every time we need YourClass we should pass the dependency manually
$instance = new YourClass($dependency);

vous pouvez enregistrer une liaison sur le conteneur de service :

//add a binding for the class YourClass 
App::bind( YourClass::class, function()
{
    //do some preliminary work: create the needed dependencies
    $dependency = new DepClass( config('some.value') );

    //create and return the object with his dependencies
    return new YourClass( $dependency );
});

et créer une instance par le biais du conteneur de service avec :

//no need to create the YourClass dependencies, the SC will do that for us!
$instance = App::make( YourClass::class );

Liaison des interfaces aux classes concrètes

Avec l'injection automatique de dépendances de Laravel, lorsqu'une interface est requise dans une partie de l'application (par exemple, dans le constructeur d'un contrôleur), une classe concrète est instanciée automatiquement par le conteneur de services. Si vous modifiez la classe concrète sur la liaison, les objets concrets instanciés dans toute votre application seront modifiés :

//everityme a UserRepositoryInterface is requested, create an EloquentUserRepository 
App::bind( UserRepositoryInterface::class, EloquentUserRepository::class ); 

//from now on, create a TestUserRepository 
App::bind( UserRepositoryInterface::class, TestUserRepository::class );

Utiliser le conteneur de services comme un registre

Vous pouvez créer et stocker des instances d'objets uniques sur le conteneur et les récupérer plus tard : en utilisant la fonction App::instance pour effectuer la liaison, et donc utiliser le conteneur comme un registre.

// Create an instance.
$kevin = new User('Kevin');

// Bind it to the service container.
App::instance('the-user', $kevin);

// ...somewhere and/or in another class...

// Get back the instance
$kevin = App::make('the-user'); 

Pour finir, le conteneur de service est essentiellement le conteneur de l'entreprise. Application : il étend l'objet Container qui récupère toutes les fonctionnalités du conteneur.

2 votes

Brillante explication, j'aime penser que l'application demande "quand cette classe est demandée, comment voulez-vous que je la construise ?".

0 votes

YourClass dépend de DepClass et DepClass a besoin d'un paramètre, c'est-à-dire config('some.value') à initialiser. Supposons que, au lieu de config('some.value') nous avons besoin d'un nombre comme paramètre de l'utilisateur. Alors quels seront les changements dans App::bind et App::make ?

20voto

Paresh Barad Points 742

Le conteneur Laravel crée une instance pour l'application complète à partir de services(class) Nous n'avons pas besoin de créer instance pour notre application comme

$myclass = new MyClass();
$mymethod = $myclass->myMethod();

App::bind

Tout d'abord, nous allons chercher à lier la méthode statique de App classe. bind c'est juste lier votre classe instance (objet) avec une application, rien de plus.

App::bind('myapp', function(){
    return new MyClass();
});

Maintenant, nous pouvons utiliser cet objet pour notre application en utilisant make une méthode statique de App classe.

$myclass = App::make(MyClass::class);
$mymethod = $myclass->myMethod();

App::singleton

Dans l'exemple ci-dessus, lorsque nous allons appeler make alors il génère chaque fois un nouveau instance de la classe, Laravel a donc une jolie solution pour Singleton Nous pouvons lier un object à notre application par singleton méthode.

App::singleton(MyClass::class, function(){
    return new MyClass();
});

Nous pouvons être résolus par make méthode. Or, nous avons toujours reçu exactement la même instance par cette méthode.

$myclass = App::make(MyClass::class);
$mymethod = $myclass->myMethod();

App::instance Nous pouvons lier une instance au conteneur et nous retournerons toujours exactement la même instance en utilisant la méthode suivante instance méthode.

$myclass = new MyClass();
App::instance(MyClass::class, $myclass);

Nous pouvons être résolus par

$myclass = App::make(MyClass::class);

Nous pouvons lier l'interface par

App::instance(MyClassInterface::class, new MyClass);

Liaison de mise en œuvre

Nous avons une question, comment pouvons-nous mettre en œuvre la liaison dans notre application ? Nous pouvons implémenter la liaison dans notre AppServiceProvider

app/Providers/AppServiceProvider.php

namespace App\Providers;

use App\SocialProvider;
use App\TwitterSocialProvider;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
  /**
   * Bootstrap any application services.
   *
   * @return void
   */
   public function boot()
  {

  }

   /**
   * Register any application services.
   *
   * @return void
   */
   public function register()
   {
      $this->app->bind(
        MyClassInterface::class,
        MyClass::class
      );
  }
}

Conclusion : Le conteneur de services permet de créer des objets de classe ou services.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X