Angulaire 2: Injecter de service dans la classe
J'ai angulaire de la classe qui représente la forme. Je veux être en mesure d'instancier plusieurs instances de cette classe à l'aide de constructeur.
Le constructeur prend plusieurs arguments représentant les propriétés de cette forme.
constructor(public center: Point, public radius: number, fillColor: string,
fillOpacity: number, strokeColor: string, strokeOpacity: number, zIndex: number)
À l'intérieur de ma classe je veux utiliser un service qui fournit une capacité à dessiner des formes sur la carte. Est-il possible d'injecter de service dans ma classe, et continuer à utiliser le constructeur de façon standard.
Donc je veux faire quelque chose comme ci-dessous et Angulaire résoudre automatiquement injecté de dépendance.
constructor(public center: GeoPoint, public radius: number,
fillColor: string, fillOpacity: number, strokeColor: string, strokeOpacity: number,
zIndex: number, @Inject(DrawingService) drawingService: DrawingService)
Vous devez vous connecter pour publier un commentaire.
J'ai réussi à résoudre mon problème.
Angulaire 2 - 4 fournit réfléchissant injecteur qui permet d'injecter des dépendances à l'extérieur des paramètres du constructeur.
Tout ce que j'avais à faire était de les importer Réfléchissant injecteur de
@angular/core
.Et puis:
La classe n'avez même pas à être décorés avec de la
@Injectable
décorateur.Le seul problème c'est que je dois fournir toutes les dépendances DrawingService et toutes imbriquées les dépendances, de sorte qu'il est difficile à maintenir.
MODIFIER:
Angulaire 5
Angulaire 6
Http
et je reçois l'erreur suivante.zone.js:355 Unhandled Promise rejection: No provider for Http!
Je suppose que je dois fournir à la dépendance que vous avez dit ici, "La classe n'ont même pas à être décorées avec @Injectable décorateur. Le seul problème c'est que je dois fournir toutes les dépendances DrawingService et toutes imbriquées les dépendances, de sorte qu'il est difficile à maintenir." Mais comment fournir toutes ces dépendances pour une classe sans @Composante décorateur?ReflectiveInjector.resolveAndCreate([MyService, Http]);
Il ne casse plus de manquants, Http, mais j'ai dû les suivants aussi la Connexion Backend, et puis il a demandé RequestOptions. Est-ce ce que vous vouliez dire avecall nested dependencies, so that is hard to maintain
?Unhandled Promise rejection: No provider for Http!
? Avoir ce problème aujourd'hui.Voici deux autres façons possibles pour atteindre l'objectif souhaité, ou très semblable résultat.
Première approche - la à l'aide d'un gestionnaire pour votre entités ou non des objets de service
Vous avez un ou plusieurs service de l'usine(s) qui est/sont responsable de l'instanciation de vos objets.
Cela signifie que il peut fournir le deps encore à des objets, et ne nécessite pas que vous les passez sur vous-même.
Par exemple, disons que vous avez entités comme une hiérarchie de classe:
Vous pouvez alors avoir un EntityManager qui est un service et peut construire des entités:
Vous pouvez aussi avoir des paramètres de construction si vous voulez (mais ils ne seront pas avoir n'importe quel type d'information, car
create
doit travailler avec tous les types d'entités):Votre entités peuvent déclarer le gestionnaire:
Et vos entités pouvez l'utiliser pour faire n'importe quoi:
Maintenant, chaque fois que vous avez besoin de créer une entité ou un objet que vous utilisez ce gestionnaire. Le
EntityManager
doit être injecté lui-même, mais les entités sont des objets libres. Mais tous angulaire code de démarrer à partir d'un contrôleur ou d'un service ou d'une telle sorte qu'il sera possible d'injecter le gestionnaire.Cette approche peut également être adapté à des objets arbitraires. Vous n'avez pas besoin d'une hiérarchie de classe, mais avec des caractères d'imprimerie cela fonctionne mieux. Il est également judicieux d'avoir une certaine classe de base pour les objets que vous pouvez ré-utiliser le code de cette vieille façon, surtout dans un domaine/l'approche orientée objet.
PROS: Cette approche est plus sûr parce qu'il se trouve encore sur la pleine DI hiérarchie et il devrait y avoir moins d'effets secondaires non désirés.
CONTRE: L'inconvénient est que vous ne pouvez jamais utiliser
new
jamais de nouveau, et vous ne pouvez obtenir l'accès à ces services en code arbitraire. Vous avez toujours besoin de s'appuyer sur la DI et de votre usine ou les usines.Deuxième approche - h4ckz0rs
Vous créer un service dédié à l'obtention d' (via DI) les services dont vous avez besoin dans les objets.
Cette partie est très semblable à la première approche, c'est juste que ce service n'est pas une usine. Au lieu de cela, il passe sur l'injection de services dans un objet qui est défini en dehors de cette classe dans un fichier différent (explication après). Par exemple:
L'objet qui va contenir le services est définie dans son propre fichier en tant que tel:
Noter que les services ne sont pas à l'aide de n'importe quel type d'information (ce qui est un inconvénient, mais nécessaire).
Ensuite, vous devez vous assurer que
ExternalServicesService
obtient injecté une fois. Le mieux est d'utiliser l'application principale composante:Enfin, vous pouvez maintenant utiliser les services de n'importe quel objet à tout moment après l'application principale composante a été instancié.
Remarque vous ne serez pas capable de composer l'un de ces services dans le code de la classe ou dans les objets non instancié après l'application est instancié. Mais dans une application classique, cela ne devrait jamais être nécessaire.
Maintenant, quelques explications au sujet de cette étrange configuration:
Pourquoi utiliser un objet
externalServices
dans un fichier séparé au lieu de le même fichier, ou tout simplement réduire les services à la classe elle-même (comme les attributs statiques) et pourquoi les services non typée?La raison en est que, lorsque vous êtes bulding le code, par exemple via angulaires-cli /webpack avec
--prod
mode, il est très probable d'obtenir cyclique des dépendances qui ne peut pas être résolu correctement et vous aurez laid erreurs qui sont difficiles à trouver -J'ai déjà vécu ça :).
Une erreur de la forme
vu que lors de l'exécution avec
--prod
drapeau suggérer le fait que les dépendances ne sont pas réglés correctement.C'est beaucoup mieux pour s'assurer que
ExternalServicesService
ne dépendexternalServices
passer les instances de service, et l'application n'injecteExternalServicesService
une fois (par exemple dans votre principale AppComponent) alors tous les code arbitraire /objets utilisera uniquementexternalServices
à obtenir les services.Ainsi, un tel code ne faut importer le
externalServices
qui n'a plus d'deps (parce que les services sont également pas tapé). Si ils étaient à l'importationExternalServicesService
il aurait importé tout le reste et n'aurait pas été en mesure de résoudre le bi-directionnelle deps de manière statique. Et cela devient un problème majeur dans ng2/webpack lorsque le regroupement pour la prod.La même arriverait-il si nous étions à utiliser des types pour les services, parce que cela va exiger
imports
.PROS: Cette approche est plus facile à utiliser une fois que l'installation a été faite, et vous êtes libre de les utiliser
new
. Fondamentalement n'importe quel fichier de code pouvez importer lesexternalServices
et d'avoir accès à ces services, vous souhaitez exposer de cette façon.CONTRE: l'inconvénient est Le hackish d'installation et les problèmes causés par cyclique de deps. Il est également plus sensible, vous ne pouvez pas être sûr
externalServices
a ces services tout de suite. Ils ne seront définis une fois pour le ng2 application démarre et leExternalServicesService
est la première injection. Un inconvénient est que vous n'avez plus le type d'informations sur ces services.PS: je ne sais pas pourquoi ce sujet n'est pas plus populaire.
Par exemple, étant un fan de domaine-conception orientée, ayant de puissantes entités (par exemple, avec des méthodes orientées au REPOS des appels ou d'interagir avec d'autres services) est important, et cette limitation fait toujours difficile.
Nous avons eu à surmonter cette limitation, à la fois dans angularjs, et à nouveau en Angular2+ comme il ne semble pas encore être abordées dans la bibliothèque.
Comme Angulaire 5.x:
En fait, vous ne pouvez pas. La classe doit être décorée avec des
@Injectable
laisser Angular2 injecter des choses. Le@Inject
décorateur est "seulement" il y spécifier des métadonnées supplémentaires au sujet de ce à injecter.Dans votre cas, la classe est géré par vous, car la plupart de son constructeur paramètres ne correspondent pas à des dépendances et sont fournis lorsque vous instancier explicitement la classe.