| 
									
										
										
										
											2015-10-17 10:01:41 -07:00
										 |  |  |  | include ../../../../_includes/_util-fns | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Dependency Injection is an important application design pattern. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Angular has its own Dependency Injection framework and | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   we really can't build an Angular application without it. | 
					
						
							| 
									
										
										
										
											2015-10-17 10:01:41 -07:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   In this chapter we'll learn what Dependency Injection is, why we want it, and how to use it. | 
					
						
							|  |  |  |  |   <a name="why-di"></a> | 
					
						
							|  |  |  |  | .l-main-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ## Why Dependency Injection? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Let's start with the following code. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   class Engine {} | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   class Tires {} | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   class Car { | 
					
						
							|  |  |  |  |     private engine: Engine; | 
					
						
							|  |  |  |  |     private tires: Tires; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     constructor() { | 
					
						
							|  |  |  |  |       this.engine = new Engine(); | 
					
						
							|  |  |  |  |       this.tires = new Tires(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     // Method using the engine and tires | 
					
						
							|  |  |  |  |     drive() {} | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Our `Car` creates everything it needs inside its constructor. | 
					
						
							|  |  |  |  |   What's the problem? | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   The problem is that our `Car` class is brittle, inflexible, and hard to test. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Our `Car` needs an engine and tires. Instead of asking for them, | 
					
						
							|  |  |  |  |   the `Car` constructor creates its own copies by "new-ing" them from | 
					
						
							|  |  |  |  |   the very specific classes, `Engine` and `Tires`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   What if the `Engine` class evolves and its constructor requires a parameter? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Our `Car` is broken and stays broken until we rewrite it along the lines of | 
					
						
							|  |  |  |  |   `this.engine = new Engine(theNewParameter)`. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We didn't care about `Engine` constructor parameters when we first wrote `Car`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   We don't really care about them now. | 
					
						
							|  |  |  |  |   But we'll *have* to start caring because | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   when the definion of `Engine` changes, our `Car` class must change. | 
					
						
							|  |  |  |  |   That makes `Car` brittle. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   What if we want to put a different brand of tires on our `Car`. Too bad. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We're locked into whatever brand the `Tires` class creates. That makes our `Car` inflexible. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Right now each new car gets its own engine. It can't share an engine with other cars. | 
					
						
							|  |  |  |  |   While that makes sense for an automobile engine, | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   we can think of other dependencies that should be shared ... like the onboard | 
					
						
							|  |  |  |  |   wireless connection to the manufacturer's service center. Our `Car` lacks the flexibility | 
					
						
							|  |  |  |  |   to share services that have been created previously for other consumers. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   When we write tests for our `Car` we're at the mercy of its hidden dependencies. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Is it even possible to create a new `Engine` in a test environment? | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   What does `Engine`itself depend upon? What does that dependency depend on? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Will a new instance of `Engine` make an asynchronous call to the server? | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We certainly don't want that going on during our tests. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   What if our `Car` should flash a warning signal when tire pressure is low. | 
					
						
							| 
									
										
										
										
											2015-12-30 19:06:52 -06:00
										 |  |  |  |   How do we confirm that it actually does flash a warning | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   if we can't swap in low-pressure tires during the test? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   We have no control over the car's hidden dependencies. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   When we can't control the dependencies, a class become difficult to test. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   How can we make `Car` more robust, more flexible, and more testable? | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   That's super easy. We probably already know what to do. We change our `Car` constructor to this: | 
					
						
							|  |  |  |  |   <a name="ctor-injection"></a> | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   constructor(engine: Engine, tires: Tires) { | 
					
						
							|  |  |  |  |     this.engine = engine; | 
					
						
							|  |  |  |  |     this.tires = tires; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   See what happened? We moved the definition of the dependencies to the constructor. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Our `Car` class no longer creates an engine or tires. | 
					
						
							|  |  |  |  |   It just consumes them. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Now we create a car by passing the engine and tires to the constructor. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   var car = new Car(new Engine(), new Tires()); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   How cool is that? | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   The definition of the engine and tire dependencies are decoupled from the `Car` class itself. | 
					
						
							|  |  |  |  |   We can pass in any kind of engine or tires we like, as long as they | 
					
						
							|  |  |  |  |   conform to the general API requirements of an engine or tires. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   If someone extends the `Engine` class, that is not `Car`'s problem. | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     The consumer of `Car` has the problem. The consumer must update the car creation code to | 
					
						
							|  |  |  |  |     something like: | 
					
						
							|  |  |  |  |     ``` | 
					
						
							|  |  |  |  |     var car = new Car(new Engine(theNewParameter), new Tires()); | 
					
						
							|  |  |  |  |     ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |     The critical point is this: `Car` itself did not have to change. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     We'll take care of the consumer's problem soon enough. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   The `Car` class is much easier to test because we are in complete control | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   of its dependencies. | 
					
						
							|  |  |  |  |   We can pass mocks to the constructor that do exactly what we want them to do | 
					
						
							|  |  |  |  |   during each test: | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   var car = new Car(new MockEngine(), new MockLowPressureTires()); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   **We just learned what Dependency Injection is**. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   It's a coding pattern in which a class receives its dependencies from external | 
					
						
							|  |  |  |  |   sources rather than creating them itself. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Cool! But what about that poor consumer? | 
					
						
							|  |  |  |  |   Anyone who wants a `Car` must now | 
					
						
							|  |  |  |  |   create all three parts: the `Car`, `Engine`, and `Tires`. | 
					
						
							|  |  |  |  |   The `Car` class shed its problems at the consumer's expense. | 
					
						
							|  |  |  |  |   We need something that takes care of assembling these parts for us. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We could write a giant class to do that: | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   class SuperFactory { | 
					
						
							|  |  |  |  |     createEngine = () => new Engine(); | 
					
						
							|  |  |  |  |     createTires =  () => new Tires(); | 
					
						
							|  |  |  |  |     createCar = () => new Car(this.createEngine(), this.createTires()); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   It's not so bad now with only three creation methods. | 
					
						
							|  |  |  |  |   But maintaining it will be hairy as the application grows. | 
					
						
							|  |  |  |  |   This `SuperFactory` is going to become a huge spider web of | 
					
						
							|  |  |  |  |   interdependent factory methods! | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Wouldn't it be nice if we could simply list the things we want to build without | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   having to define which dependency gets injected into what? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   This is where the Dependency Injection Framework comes into play. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Imagine the framework had something called an `Injector`. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We register some classes with this `Injector` and it figures out how to create them. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   When we need a `Car`, we simply ask the `Injector` to get it for us and we're good to go. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   function main() { | 
					
						
							|  |  |  |  |     var injector = new Injector([Car, Engine, Tires, Logger]); | 
					
						
							|  |  |  |  |     var car = injector.get(Car); | 
					
						
							|  |  |  |  |     car.drive(); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   Everyone wins. The `Car` knows nothing about creating an `Engine` or `Tires`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   The consumer knows nothing about creating a `Car`. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We don't have a gigantic factory class to maintain. | 
					
						
							|  |  |  |  |   Both `Car` and consumer simply ask for what they need and the `Injector` delivers. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   This is what a **Dependency InjectionFramework** is all about. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Now that we know what Dependency Injection is and appreciate its benefits, | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   let's see how it is implemented in Angular. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 10:01:41 -07:00
										 |  |  |  | .l-main-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ## Angular Dependency Injection | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Angular ships with its own Dependency Injection framework. This framework can also be used | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   as a standalone module by other applications and frameworks. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   That sounds nice. What does it do for us when building components in Angular? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Let's see, one step at a time. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   We'll begin with a simplified version of the `HeroesComponent` | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   that we built in the [The Tour of Heroes](../tutorial/). | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   import {Component} from 'angular2/angular2'; | 
					
						
							|  |  |  |  |   import {Hero} from './hero'; | 
					
						
							|  |  |  |  |   import {HEROES} from './mock-heroes'; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   @Component({ | 
					
						
							|  |  |  |  |     selector: 'my-heroes' | 
					
						
							|  |  |  |  |     templateUrl: 'app/heroes.component.html' | 
					
						
							|  |  |  |  |   }) | 
					
						
							|  |  |  |  |   export class HeroesComponent { | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     heroes: Hero[] = HEROES; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   It assigns a list of mocked heroes to its `heroes` property for binding within the template. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Pretty straight forward. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   Those heroes are currently a fixed, in-memory collection, defined in another file and imported by the component. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   That works in the early stages of development but it's far from ideal. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   As soon as we try to test this component or want to get our heroes data from a remote server, | 
					
						
							|  |  |  |  |   we'll have to change this component's implementation of `heroes` and | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   fix every other use of the `HEROES` mock data. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Let's make a service that hides how we get Hero data. | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     Write this service in its own file. See [this note](#forward-ref) to understand why. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   import {Hero} from './hero'; | 
					
						
							|  |  |  |  |   import {HEROES} from './mock-heroes'; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   class HeroService { | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     heroes: Hero[]; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     constructor() { | 
					
						
							|  |  |  |  |       this.heroes = HEROES; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     getHeroes() { | 
					
						
							|  |  |  |  |       return this.heroes; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Our `HeroService` exposes a `getHeroes()` method that returns | 
					
						
							|  |  |  |  |   the same mock data as before but none of its consumers need to know that. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   A service is nothing more than a class in Angular 2. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   It remains nothing more than a class until we register it with | 
					
						
							|  |  |  |  |   the Angular injector. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### Configuring the Injector | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We don't have to create the injector. | 
					
						
							|  |  |  |  |   <a name="bootstrap"></a> | 
					
						
							|  |  |  |  |   Angular creates an application-wide injector for us during the bootstrap process. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   bootstrap(HeroesComponent); | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   Let’s configure the injector at the same time that we bootstrap by adding | 
					
						
							|  |  |  |  |   our `HeroService` to an array in the second argument. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We'll explain that array when we talk about [providers](#providers) later in this chapter. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   bootstrap(AppComponent, [HeroService]); | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   That’s it! The injector now knows about the `HeroService` which is available for injection across our entire application. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### Preparing the `HeroesComponent` for injection | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   The `HeroesComponent` should get its heroes from this service. | 
					
						
							|  |  |  |  |   Per the dependency injection pattern, the component must "ask for" the service in its constructor [as we explained | 
					
						
							|  |  |  |  |   earlier](#ctor-injection)". | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   constructor(heroService: HeroService) { | 
					
						
							|  |  |  |  |     this.heroes = heroService.getHeroes(); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   <a name="di-metadata"></a> | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     Adding a parameter to the constructor isn't all that's happening here. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     We are writing the app in TypeScript and have followed the parameter name with a type notation, `:HeroService`. | 
					
						
							|  |  |  |  |     The class is also decorated with the `@Component` decorator (scroll up to confirm that fact). | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     When the TypeScript compiler evaluates this class, it sees the decorator and adds class metadata | 
					
						
							|  |  |  |  |     into the generated JavaScript code. Within that metadata lurks the information that | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |     associates the `heroService` parameter with the `HeroService` class. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     That's how the Angular injector will know to inject an instance of the `HeroService` when it | 
					
						
							|  |  |  |  |     creates a new `HeroesComponent`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### Creating the `HeroesComponent` with the injector (implicitly) | 
					
						
							|  |  |  |  |   When we introduced the idea of an injector above, we showed how to create | 
					
						
							|  |  |  |  |   a new `Car` with that injector. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   var car = injector.get(Car); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   Search the entire Tour of Heroes source. We won't find a single line like | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   var hc = injector.get(HeroesComponent); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   We *could* write code like that if we wanted to. We just don't have to. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Angular does that for us when it renders a `HeroesComponent` | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   whether we ask for it in an HTML template ... | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   <my-heroes></heroes> | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   ... or navigate to a `HeroesComponent` view with the [router](./router.html). | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   ### Singleton services | 
					
						
							|  |  |  |  |   We might wonder what happens when we inject the `HeroService` into other components. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Do we get the same instance every time? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Yes we do. Dependencies are singletons. | 
					
						
							|  |  |  |  |   We’ll discuss that later in our chapter about | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   [Hierarchical Injectors](./hierarchical-dependency-injection.html). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   ### Testing the component | 
					
						
							|  |  |  |  |   We emphasized earlier that designing a class for dependency injection makes it easier to test. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Mission accomplished!  We don't even need the Angular Dependency Injection system to test the `HeroesComponent`. | 
					
						
							| 
									
										
										
										
											2015-11-21 20:05:50 -06:00
										 |  |  |  |   We simply create a new `HeroesComponent` with a mock service and poke at it: | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-19 23:48:46 +01:00
										 |  |  |  |   it("should have heroes when created", () => { | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     let hc = new HeroesComponent(mockService); | 
					
						
							|  |  |  |  |     expect(hc.heroes.length).toEqual(mockService.getHeroes().length); | 
					
						
							| 
									
										
										
										
											2015-10-19 23:48:46 +01:00
										 |  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   ### When the service needs a service | 
					
						
							|  |  |  |  |   Our `HeroService` is very simple. It doesn't have any dependencies of its own. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   What if it had a dependency? What if it reported its activities through a logging service? | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   We'd apply the same "constructor injection" pattern. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Here's a rewrite of `HeroService` with a new constructor that takes a `logger` parameter. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-13 15:37:50 -05:00
										 |  |  |  |   import {Injectable} from 'angular2/angular2'; | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   import {Hero} from './hero'; | 
					
						
							|  |  |  |  |   import {HEROES} from './mock-heroes'; | 
					
						
							|  |  |  |  |   import {Logger} from './logger'; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   @Injectable() | 
					
						
							|  |  |  |  |   class HeroService { | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     heroes: Hero[]; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     constructor(private logger: Logger) { | 
					
						
							|  |  |  |  |       this.heroes = HEROES; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     getHeroes() { | 
					
						
							|  |  |  |  |       this.logger.log('Getting heroes ...') | 
					
						
							|  |  |  |  |       return this.heroes; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   The constructor now asks for an injected instance of a `Logger` and stores it in a private property called `logger`. | 
					
						
							|  |  |  |  |   We call that property within our `getHeroes()` method when anyone asks for heroes. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   **The `@Injectable()` decoration catches our eye!** | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  | .alert.is-critical | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							|  |  |  |  |     **Always include the parentheses!** Always call `@Injectable()`. It's easy to forget the parentheses. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     Our application will fail mysteriously if we do. It bears repeating: **always include the parentheses.** | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							|  |  |  |  |   We haven't seen `@Injectable()` before. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   As it happens, we could have added it to `HeroService`. We didn't bother because we didn't need it then. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   We need it now ... now that our service has an injected dependency. | 
					
						
							|  |  |  |  |   We need it because Angular requires constructor parameter metadata in order to inject a `Logger`. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   As [we mentioned earlier](#di-metadata), TypeScript *only generates metadata for classes that have a decorator*. . | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   The `HeroesComponent` has an injected dependency too. Why don't we add `@Injectable()` to the `HeroesComponent`? | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We *can* add it if we really want to. It isn't necessary because the `HeroesComponent` is already decorated with `@Component`. | 
					
						
							|  |  |  |  |   TypeScript generates metadata for *any* class with a decorator and *any* decorator will do. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  | .l-main-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   <a name="providers"></a> | 
					
						
							|  |  |  |  |   ## Injector Providers | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Remember when we added the `HeroService` to an array in the [bootstrap](#bootstrap) process? | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   bootstrap(AppComponent, [HeroService]); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   That list of classes is actually a list of **providers**. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   "Providers" create the instances of the things that we ask the injector to inject. | 
					
						
							| 
									
										
										
										
											2015-11-17 11:02:00 +01:00
										 |  |  |  |   There are many ways to "provide" a thing that has the necessary shape and behavior to serve as a `HeroService`. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   A class is a natural provider - it's meant to be created. But it's not the only way | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   to produce something injectable. We could hand the injector an object to return. We could give it a factory function to call. | 
					
						
							|  |  |  |  |   Any of these approaches might be a good choice under the right circumstances. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   What matters is that the injector knows what to do when something asks for a `HeroService`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   ### The Provider Class | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   When we wrote ... | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   [HeroService]; | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   we used a short-hand expression for provider registration. | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   Angular expanded that short-hand into a call to the Angular `provide` method | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   [provide(HeroService, {useClass:HeroService})]; | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   and the `provide` method in turn creates a new instance of the Angular | 
					
						
							| 
									
										
										
										
											2015-11-30 15:09:57 -06:00
										 |  |  |  |   [Provider class](/docs/ts/latest/api/core/Provider-class.html): | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   [new Provider(HeroService, {useClass:HeroService})] | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   This provider instance associates a `HeroService` *token* | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   with code that can create an *instance* of a `HeroService`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   The first parameter is the [token](#token) that serves as the key for both locating a dependency value | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   and registering the provider. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   The second parameter is a provider definition object | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   which we think of as a "recipe" for creating the dependency value. | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   There are many ways to create dependency values ... and many ways to write a recipe. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### Alternative Class Providers | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   Occasionally we'll ask a different class to  provide the service. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We do that regularly when testing a component that we're creating with dependency injection. | 
					
						
							|  |  |  |  |   In this example, we tell the injector | 
					
						
							|  |  |  |  |   to return a `MockHeroService` when something asks for the `HeroService`. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   beforeEachProviders(() => [ | 
					
						
							|  |  |  |  |     provide(HeroService, {useClass: MockHeroService}); | 
					
						
							|  |  |  |  |   ]); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   ### Value Providers | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Sometimes it's easier to provide a ready-made object rather than ask the injector to create it from a class. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We do that a lot when we write tests. We might write the following test setup | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   for  tests that explore how the `HeroComponent` behaves when the `HeroService` | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   returns an empty hero list. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   beforeEachProviders(() => { | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     let emptyHeroService = { getHeroes: () => [] }; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     return [ provide(HeroService, {useValue: emptyHeroService}) ]; | 
					
						
							|  |  |  |  |   }); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   Notice we defined the recipe with `useValue` instead of `useClass`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### Factory Providers | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Sometimes the best choice for a provider is neither a class nor a value. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Suppose our HeroService has some cool new feature that we're only offering to "special" users. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   The HeroService shouldn't know about users and | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   we won't know if the current user is special until runtime anyway. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   We decide to extend our `HeroService` constructor to accept a `useCoolFeature` flag | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   that toggles the feature on or off. | 
					
						
							|  |  |  |  |   We rewrite the `HeroService` again as follows. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   @Injectable() | 
					
						
							|  |  |  |  |   class HeroService { | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     heroes: Hero[]; | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     constructor(private logger: Logger, private useCoolFeature: boolean) { | 
					
						
							|  |  |  |  |       this.heroes = HEROES; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     getHeroes() { | 
					
						
							|  |  |  |  |       let msg = this.useCoolFeature ? 'the cool new way' : 'the old way'; | 
					
						
							|  |  |  |  |       this.logger.log('Getting heroes ...' + msg) | 
					
						
							|  |  |  |  |       return this.heroes; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   The feature flag is a simple boolean value. We'd like to inject the flag but it seems silly to write an entire class for a | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   simple flag. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We can replace the `HeroService` provider with a factory function that creates a properly configured `HeroService` for the current user. | 
					
						
							|  |  |  |  |   We'll' build up to that result, beginning with our definition of the factory function: | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   let heroServiceFactory = (logger: Logger, userService: UserService) => { | 
					
						
							|  |  |  |  |     return new HeroService(logger, userService.user.isSpecial); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							|  |  |  |  |     The factory takes two parameters: the logger service and a user service. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     The logger we pass straight to the constructor as we did before. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     We'll know to use the cool new feature if the `userService.user.isSpecial` flag is true, | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     a fact we can't know until runtime. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							|  |  |  |  |   We use dependency injection everywhere so of course the factory function depends on | 
					
						
							|  |  |  |  |   two injected services: `Logger` and `UserService`. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We declare those requirements in our provider definition object: | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   let heroServiceDefinition = { | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |      useFactory: heroServiceFactory, | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |      deps: [Logger, UserService] | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     The `useFactory` field tells Angular that the provider is a factory function and that its implementation is the `heroServiceFactory`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     The `deps` property is an array of [provider tokens](#token). | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |     The `Logger` and `UserService` classes serve as tokens for their own class providers. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							|  |  |  |  |   Finally, we create the provider and adjust the bootstrapping to include that provider | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   among its provider registrations. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   let heroServiceProvider = provide(HeroService, heroServiceDefinition); | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   bootstrap(AppComponent, [heroServiceProvider, Logger, UserService]); | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### String tokens | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Sometimes we have an object dependency rather than a class dependency. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Applications often define configuration objects with lots of small facts like the title of the application or the address of a web api endpoint. | 
					
						
							|  |  |  |  |   These configuration objects aren't always instances of a class. They're just objects ... like this one: | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   let config = { | 
					
						
							|  |  |  |  |     apiEndpoint: 'api.heroes.com', | 
					
						
							|  |  |  |  |     title: 'The Hero Employment Agency' | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   We'd like to make this `config` object available for injection. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We know we can register an object with a "Value Provider". But what do we use for the token? | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   <a id="token"></a> | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Until now, we've always asked the class to play the token role | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   whether we wrote a provider with a class, value, or factory recipe. | 
					
						
							|  |  |  |  |   This time we don't have a class to serve as a token. There is no `Config` class. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   Fortunately, the token can be a string, a class type, or an | 
					
						
							| 
									
										
										
										
											2015-11-30 15:09:57 -06:00
										 |  |  |  |   [OpaqueToken](/docs/ts/latest/api/core/OpaqueToken-class.html). | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   Internally, the `Provider` turns the string and class parameter into an `OpaqueToken`; | 
					
						
							|  |  |  |  |   the injector locates dependency values and providers by this token. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   We'll register our configuration object with a string-based token! | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   bootstrap(AppComponent, [ | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |     // other providers // | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     provide('App.config', {useValue:config}) | 
					
						
							|  |  |  |  |   ]); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Let's apply what we've learned and update the `HeroesComponent` constructor so it can display the configured title. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Right now the constructor signature is | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   constructor(heroService: HeroService) | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-10-27 12:57:50 -07:00
										 |  |  |  |   We might think we can add the `config` dependency by writing: | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   // FAIL! | 
					
						
							|  |  |  |  |   constructor(heroService: HeroService, config: config) | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   That's not going to work. There is no type called `config` and we didn't register the `config` object under that name anyway. | 
					
						
							|  |  |  |  |   We'll need a little help from another Angular decorator called `@Inject`. | 
					
						
							|  |  |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2015-11-02 13:21:01 +02:00
										 |  |  |  |   import {Inject} from 'angular2/angular2' | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   constructor(heroService: HeroService, @Inject('app.config') config) | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .l-main-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   # Next Steps | 
					
						
							|  |  |  |  |   We learned the basics of Angular Dependency Injection in this chapter. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   The Angular Dependency Injection is more capable than we've described. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We can learn more about its advanced features, beginning with its support for | 
					
						
							| 
									
										
										
										
											2015-11-19 16:59:22 -08:00
										 |  |  |  |   nested injectors, in the  | 
					
						
							|  |  |  |  |   [Hierarchical Dependency Injection](./hierarchical-dependency-injection.html) chapter. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  | .l-main-section | 
					
						
							|  |  |  |  | <a name="forward-ref"></a> | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ### Appendix: Why we recommend one class per file | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Developers expect one class per file. Multiple classes per file is confusing and is best avoided. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   If we define every class in its own file, there is nothing in this note to worry about. | 
					
						
							|  |  |  |  |   Move along! | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   If we scorn this advice | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   and we add our `HeroService` class to the `HeroesComponent` file anyway, | 
					
						
							|  |  |  |  |   **define the `HeroesComponent` last!** | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   If we put it define component before the service, | 
					
						
							|  |  |  |  |   we'll get a runtime null reference error. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   To understand why, paste the following incorrect, ultra-simplified rendition of these two | 
					
						
							|  |  |  |  |   classes into the [TypeScript playground](http://www.typescriptlang.org/Playground). | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  |   class HeroesComponent { | 
					
						
							|  |  |  |  |     static $providers=[HeroService] | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   class HeroService { } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   alert(HeroesComponent.$providers) | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   :marked | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     The `HeroService` is incorrectly defined below the `HeroComponent`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     The `$providers` static property represents the metadata about the injected `HeroService` | 
					
						
							|  |  |  |  |     that TypeScript compiler would add to the component class. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     The `alert` simulates the action of the Dependency Injector at runtime | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |     when it attempts to create a `HeroesComponent`. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | :marked | 
					
						
							|  |  |  |  |   Run it. The alert appears but displays nothing. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   This is the equivalent of the null reference error thrown at runtime. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   We understand why when we review the generated JavaScript which looks like this: | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  |   var HeroesComponent = (function () { | 
					
						
							|  |  |  |  |       function HeroesComponent() { | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       HeroesComponent.$providers = [HeroService]; | 
					
						
							|  |  |  |  |       return HeroesComponent; | 
					
						
							|  |  |  |  |   })(); | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   var HeroService = (function () { | 
					
						
							|  |  |  |  |       function HeroService() { | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       return HeroService; | 
					
						
							|  |  |  |  |   })(); | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   alert(HeroesComponent.$providers); | 
					
						
							|  |  |  |  |   ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   Notice that the TypeScript compiler turns classes into function expressions | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   assigned to variables. The value of the captured `HeroService` variable is undefined | 
					
						
							|  |  |  |  |   when the `$providers` array is assigned. The `HeroService` variable gets its value too late | 
					
						
							|  |  |  |  |   to be captured. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Reverse the order of class definition so that the  `HeroService` | 
					
						
							|  |  |  |  |   appears before the `HeroesComponent` that requires it. | 
					
						
							|  |  |  |  |   Run again. This time the alert displays the `HeroService` function definition. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   If we insist on defining the `HeroService` in the same file and insist on | 
					
						
							|  |  |  |  |   defining the component first, Angular offers a way to make that work. | 
					
						
							| 
									
										
										
										
											2015-11-10 18:31:46 +00:00
										 |  |  |  |   The `forwardRef()` method let's us reference a class | 
					
						
							|  |  |  |  |   before it has been defined. | 
					
						
							| 
									
										
										
										
											2015-10-17 16:40:10 -07:00
										 |  |  |  |   Learn more about this problem and the `forwardRef()` | 
					
						
							|  |  |  |  |   in this [blog post](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html). |