51 votes

Comment puis-je accéder à un service en dehors d'un contrôleur avec Symfony2?

Je suis en train de construire un site qui s'appuie très fortement sur un tiers de l'API j'ai donc pensé qu'il serait logique pour empaqueter l'API wrapper comme un service, mais je commence à trouver des cas où il serait utile d'avoir accès à l'extérieur d'un contrôleur dans une entité référentiel. Également à ce sujet est qu'il serait utile d'être en mesure d'obtenir l'accès à la config de valeurs en dehors d'un contrôleur (encore une fois comme dans une entité référentiel).

Quelqu'un peut-il me dire si cela est possible et si ce n'est là qu'une approche suggérée pour faire ce genre de chose?

merci pour toute aide

74voto

Matt Points 5550

Le Symfony distribution s'appuie fortement sur l'injection de dépendance. Cela signifie que, en général, les dépendances sont injectées directement dans votre objet via le constructeur, les incubateurs ou par d'autres moyens (comme la réflexion sur les propriétés). Votre API service wrapper est alors une dépendance pour les autres objets de votre application.

Cela étant dit, il serait assez difficile d'injecter de ce service dans une entité référentiel du constructeur, car elle exige déjà que certains autres paramètres et je pense qu'il ne serait pas possible de les injecter à cause de la façon dont nous demande le dépôt d'une entité.

Ce que vous pourriez faire est de créer un autre service qui sera chargé de faire le travail que vous aviez à faire dans l'entité de référentiel. De cette façon, vous serez en mesure d'injecter le gestionnaire de l'entité, qui sera utilisée pour récupérer l'entité référentiel, vous service personnalisé et aussi un autre service de tenue de vos valeurs de configuration (Il y a d'autres façons de partager les valeurs de configuration).

Dans mon cas d'utilisation, j'utilise un Facebook le service d'assistance qui encapsule Facebook des appels d'API. Ce service est ensuite injecté où j'en ai besoin. Mon entité référentiel n'est responsable que de faire des appels de base de données de sorte qu'il ne reçoit que les arguments dont il a besoin et non pas à l'ensemble de la dépendance. Ainsi, il ne recevra pas l'aide, mais plutôt que les arguments nécessaires pour faire une demande, par exemple, un Facebook id d'utilisateur. À mon avis, c'est la façon de le faire, car je pense que l'entité référentiel ne devrait pas avoir de dépendances sur de tels objets d'assistance.

Voici un petit exemple d'utilisation de DONNÉES de configuration:

# app/config/config.yml
services:
  yourapp.configuration_container:
    class: Application/AcmeBundle/Common/ConfigurationContainer
    # You could inject configurations here      

  yourapp.api_wrapper:
    class: Application/AcmeBundle/Service/ApiWrapperService
    # Inject other arguments if needed and update constructor in consequence    

  yourapp.data_access:
    class: Application/AcmeBundle/Data/Access/DatabaseAccessService
    arguments: 
      entityManager: "@doctrine.orm.entity_manager"
      apiWrapperService: "@yourapp.api_wrapper"
      configuration: "@yourapp.configuration_container"

# Application/AcmeBundle/Common/ConfigurationContainer.php
public ConfigurationContainer
{
   public function __construct()
   {
       // Initialize your configuration values or inject them in the constructor
   }
}        

# Application/AcmeBundle/Service/ApiWrapperService.php
public ApiWrapperService
{
   public function __construct()
   {
       // Do some stuff
   }
}

# Application/AcmeBundle/Data/Access/DatabaseAccessService.php
public DatabaseAccessService
{
    public function __construct(EntityManager $entityManager, ApiWrapperService $apiWrapperService, ConfigurationContainer $configuration)
    {
        ...
    }
}

Le signe arobase (@) dans la config.fichier yml signifie que Symfony injecter dans un autre service ,ayant l'id défini après le signe, et non pas une simple chaîne de caractères. Pour les valeurs de configuration, comme je l'ai dit précédemment, il y a d'autres moyens pour atteindre le même objectif, comme l'utilisation de paramètres ou un bundle extension. Avec un paquet d'extension, vous pouvez définir les valeurs de configuration directement dans le fichier de configuration.yml et votre grappe de les lire.

En conclusion, cela devrait vous donner une idée générale de l'injection de services. Voici une petite liste de la documentation sur le sujet. Beaucoup de liens d'utiliser le XML de définition de service au lieu de la définition YAML, mais vous devriez être capable de comprendre assez facilement.

  1. Symfony Officiel DI
  2. Fabien Potencier articles sur la DI
  3. Richard Miller, articles sur la DI (Vérifiez dans son blog pour les autres DI articles)

Prendre note que la configuration que je suis en train de faire est de travailler pour Beta1 de Symfony2. Je n'ai pas encore mettre à jour à Beta2 il pourrait donc y avoir certaines choses ne fonctionnent pas comme ils sont dans la version Beta2.

J'espère que cela va vous aider à la définition d'une solution définitive à votre problème. N'hésitez pas à poser d'autres questions si vous voulez des précisions ou quoi que ce soit d'autre.

En ce qui concerne, Matt

0voto

shacharsol Points 496

Je voudrais envelopper ce genre de comportement dans un service Symfony (comme un gestionnaire). Je n'injecterais aucun paramètre ni aucune logique dans les référentiels d'entités, car ils devraient principalement être utilisés pour récupérer des données à l'aide de requêtes de gestionnaire d'objets. Je mettrais la logique dans les services et si le service nécessite un accès à la base de données, il appellera le référentiel d'entités pour récupérer les données.

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