875 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			875 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
include ../_util-fns
 | 
						|
 | 
						|
:marked
 | 
						|
  Dependency Injection is a powerful pattern for managing code dependencies. 
 | 
						|
  In this cookbook we will explore many of the features of Dependency Injection (DI) in Angular.
 | 
						|
  
 | 
						|
<a id="toc"></a>
 | 
						|
:marked
 | 
						|
  ## Table of contents
 | 
						|
 | 
						|
  [Application-wide dependencies](#app-wide-dependencies)
 | 
						|
 | 
						|
  [External module configuration](#external-module-configuration)
 | 
						|
 | 
						|
  [*@Injectable* and nested service dependencies](#nested-dependencies)
 | 
						|
 | 
						|
  [Limit service scope to a component subtree](#service-scope)
 | 
						|
 | 
						|
  [Multiple service instances (sandboxing)](#multiple-service-instances)
 | 
						|
 | 
						|
  [Qualify dependency lookup with *@Optional* and *@Host*](#qualify-dependency-lookup)
 | 
						|
 | 
						|
  [Inject the component's DOM element](#component-element)
 | 
						|
 | 
						|
  [Define dependencies with providers](#providers)
 | 
						|
  * [The *provide* object literal](#provide)
 | 
						|
  * [useValue - the *value provider*](#usevalue)
 | 
						|
  * [useClass - the *class provider*](#useclass)
 | 
						|
  * [useExisting - the *alias provider*](#useexisting)
 | 
						|
  * [useFactory - the *factory provider*](#usefactory)
 | 
						|
 | 
						|
  [Provider token alternatives](#tokens)
 | 
						|
  * [class-interface](#class-interface)
 | 
						|
  * [OpaqueToken](#opaque-token)
 | 
						|
  
 | 
						|
  [Inject into a derived class](#di-inheritance)
 | 
						|
  
 | 
						|
  [Find a parent component by injection](#find-parent)
 | 
						|
    * [Find parent with a known component type](#known-parent)
 | 
						|
    * [Cannot find a parent by its base class](#base-parent)
 | 
						|
    * [Find a parent by its class-interface](#class-interface-parent)
 | 
						|
    * [Find a parent in a tree of parents (*@SkipSelf*)](#parent-tree)
 | 
						|
    * [A *provideParent* helper function](#provideparent)
 | 
						|
  
 | 
						|
  [Break circularities with a forward class reference (*forwardRef*)](#forwardref)
 | 
						|
  
 | 
						|
:marked
 | 
						|
   **See the <live-example name="cb-dependency-injection"></live-example>**
 | 
						|
   of the code supporting this cookbook.        
 | 
						|
   
 | 
						|
.l-main-section
 | 
						|
 | 
						|
<a id="app-wide-dependencies"></a>
 | 
						|
:marked
 | 
						|
  ## Application-wide dependencies   
 | 
						|
  Register providers for dependencies used throughout the application in the root application component, `AppComponent`.
 | 
						|
  
 | 
						|
  In the following example, we import and register several services 
 | 
						|
  (the `LoggerService`, `UserContext`, and the `UserService`)
 | 
						|
  in the `@Component` metadata `providers` array.
 | 
						|
 | 
						|
+makeExample('cb-dependency-injection/ts/app/app.component.ts','import-services','app/app.component.ts (excerpt)')(format='.') 
 | 
						|
:marked
 | 
						|
  All of these services are implemented as classes. 
 | 
						|
  Service classes can act as their own providers which is why listing them in the `providers` array
 | 
						|
  is all the registration we need.
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    A *provider* is something that can create or deliver a service.
 | 
						|
    Angular creates a service instance from a class provider by "new-ing" it.
 | 
						|
    Learn more about providers [below](#providers).
 | 
						|
:marked
 | 
						|
  Now that we've registered these services, 
 | 
						|
  Angular can inject them into the constructor of *any* component or service, *anywhere* in the application.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','ctor','app/hero-bios.component.ts (component constructor injection)')(format='.') 
 | 
						|
 | 
						|
+makeExample('cb-dependency-injection/ts/app/user-context.service.ts','ctor','app/user-context.service.ts (service constructor injection)')(format='.')    
 | 
						|
    
 | 
						|
<a id="external-module-configuration"></a>
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## External module configuration
 | 
						|
  We often register providers in the `NgModule` rather than in the root application component.
 | 
						|
  
 | 
						|
  We do this when (a) we expect the service to be injectable everywhere
 | 
						|
  or (b) we must configure another application global service _before it starts_.
 | 
						|
  
 | 
						|
  We see an example of the second case here, where we configure the Component Router with a non-default
 | 
						|
  [location strategy](../guide/router.html#location-strategy) by listing its provider 
 | 
						|
  in the `providers` list of the `AppModule`.
 | 
						|
  
 | 
						|
+makeExample('cb-dependency-injection/ts/app/app.module.ts','providers','app/app.module.ts (providers)')(format='.') 
 | 
						|
 | 
						|
a(id="injectable")
 | 
						|
a(id="nested-dependencies")
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## *@Injectable* and nested service dependencies
 | 
						|
  The consumer of an injected service does not know how to create that service.
 | 
						|
  It shouldn't care.
 | 
						|
  It's the dependency injection's job to create and cache that service.
 | 
						|
  
 | 
						|
  Sometimes a service depends on other services ... which may depend on yet other services.
 | 
						|
  Resolving these nested dependencies in the correct order is also the framework's job.
 | 
						|
  At each step, the consumer of dependencies simply declares what it requires in its constructor and the framework takes over.
 | 
						|
  
 | 
						|
  For example, we inject both the `LoggerService` and the `UserContext` in the `AppComponent`. 
 | 
						|
+makeExample('cb-dependency-injection/ts/app/app.component.ts','ctor','app/app.component.ts')(format='.') 
 | 
						|
 | 
						|
:marked
 | 
						|
  The `UserContext` in turn has dependencies on both the `LoggerService` (again) and 
 | 
						|
  a `UserService` that gathers information about a particular user.
 | 
						|
  
 | 
						|
+makeExample('cb-dependency-injection/ts/app/user-context.service.ts','injectables','user-context.service.ts (injection)')(format='.')
 | 
						|
 | 
						|
:marked
 | 
						|
 When Angular creates an`AppComponent`, the dependency injection framework creates an instance of the `LoggerService` and 
 | 
						|
 starts to create the `UserContextService`.
 | 
						|
 The `UserContextService` needs the `LoggerService`, which the framework already has, and the `UserService`, which it has yet to create. 
 | 
						|
 The `UserService` has no dependencies so the dependency injection framework can just `new` one into existence.
 | 
						|
 
 | 
						|
 The beauty of dependency injection is that the author of `AppComponent` didn't care about any of this. 
 | 
						|
 The author simply declared what was needed in the constructor (`LoggerService` and `UserContextService`) and the framework did the rest.
 | 
						|
 
 | 
						|
 Once all the dependencies are in place, the `AppComponent` displays the user information:
 | 
						|
  
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/logged-in-user.png" alt="Logged In User")
 | 
						|
:marked
 | 
						|
  ### *@Injectable()*
 | 
						|
  Notice the `@Injectable()`decorator on the `UserContextService` class. 
 | 
						|
+makeExample('cb-dependency-injection/ts/app/user-context.service.ts','injectable','user-context.service.ts (@Injectable)')(format='.')
 | 
						|
:marked
 | 
						|
  That decorator makes it possible for Angular to identify the types of its two dependencies, `LoggerService` and `UserService`.
 | 
						|
  
 | 
						|
  Technically, the `@Injectable()`decorator is only _required_ for a service class that has _its own dependencies_.
 | 
						|
  The `LoggerService` doesn't depend on anything. The logger would work if we omitted `@Injectable()`
 | 
						|
  and the generated code would be slightly smaller. 
 | 
						|
  
 | 
						|
  But the service would break the moment we gave it a dependency and we'd have to go back and
 | 
						|
  and add `@Injectable()` to fix it. We add `@Injectable()` from the start for the sake of consistency and to avoid future pain.
 | 
						|
 | 
						|
.alert.is-helpful
 | 
						|
  :marked
 | 
						|
    Although we recommend applying `@Injectable` to all service classes, do not feel bound by it.
 | 
						|
    Some developers prefer to add it only where needed and that's a reasonable policy too.
 | 
						|
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    The `AppComponent` class had two dependencies as well but no `@Injectable()`.
 | 
						|
    It didn't need `@Injectable()` because that component class has the `@Component` decorator.
 | 
						|
    In Angular with TypeScript, a *single* decorator — *any* decorator — is sufficient to identify dependency types.
 | 
						|
 | 
						|
 | 
						|
<a id="service-scope"></a>
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Limit service scope to a component subtree
 | 
						|
  
 | 
						|
  All injected service dependencies are singletons meaning that, 
 | 
						|
  for a given dependency injector ("injector"), there is only one instance of service. 
 | 
						|
  
 | 
						|
  But an Angular application has multiple dependency injectors, arranged in a tree hierarchy that parallels the component tree.
 | 
						|
  So a particular service can be *provided* (and created) at any component level and multiple times
 | 
						|
  if provided in multiple components.
 | 
						|
  
 | 
						|
  By default, a service dependency provided in one component is visible to all of its child components and 
 | 
						|
  Angular injects the same service instance into all child components that ask for that service.
 | 
						|
  
 | 
						|
  Accordingly, dependencies provided in the root `AppComponent` can be injected into *any* component *anywhere* in the application.
 | 
						|
  
 | 
						|
  That isn't always desirable. 
 | 
						|
  Sometimes we want to restrict service availability to a particular region of the application.
 | 
						|
  
 | 
						|
  We can limit the scope of an injected service to a *branch* of the application hierarchy
 | 
						|
  by providing that service *at the sub-root component for that branch*.
 | 
						|
  Here we provide the `HeroService` to the `HeroesBaseComponent` by listing it in the `providers` array:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/sorted-heroes.component.ts','injection','app/sorted-heroes.component.ts (HeroesBaseComponent excerpt)')
 | 
						|
:marked
 | 
						|
  When Angular creates the `HeroesBaseComponent`, it also creates a new instance of `HeroService` 
 | 
						|
  that is visible only to the component and its children (if any).
 | 
						|
  
 | 
						|
  We could also provide the `HeroService` to a *different* component elsewhere in the application. 
 | 
						|
  That would result in a *different* instance of the service, living in a *different* injector.
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    We examples of such scoped `HeroService` singletons appear throughout the accompanying sample code, 
 | 
						|
    including the `HeroBiosComponent`, `HeroOfTheMonthComponent`, and `HeroesBaseComponent`. 
 | 
						|
    Each of these components has its own `HeroService` instance managing its own independent collection of heroes.
 | 
						|
 | 
						|
.l-main-section
 | 
						|
.alert.is-helpful
 | 
						|
  :marked
 | 
						|
    ### Take a break!
 | 
						|
    This much Dependency Injection knowledge may be all that many Angular developers
 | 
						|
    ever need to build their applications. It doesn't always have to be more complicated.
 | 
						|
    
 | 
						|
<a id="multiple-service-instances"></a>
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Multiple service instances (sandboxing)
 | 
						|
  
 | 
						|
  Sometimes we want multiple instances of a service at *the same level of the component hierarchy*.
 | 
						|
  
 | 
						|
  A good example is a service that holds state for its companion component instance. 
 | 
						|
  We need a separate instance of the service for each component.
 | 
						|
  Each service has its own work-state, isolated from the service-and-state of a different component.
 | 
						|
  We call this *sandboxing* because each service and component instance has its own sandbox to play in.
 | 
						|
  
 | 
						|
  <a id="hero-bios-component"></a>
 | 
						|
  Imagine a `HeroBiosComponent` that presents three instances of the `HeroBioComponent`. 
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','simple','ap/hero-bios.component.ts')
 | 
						|
:marked
 | 
						|
  Each `HeroBioComponent` can edit a single hero's biography. 
 | 
						|
  A `HeroBioComponent` relies on a `HeroCacheService` to fetch, cache, and perform other persistence operations on that hero.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-cache.service.ts','service','app/hero-cache.service.ts')  
 | 
						|
:marked
 | 
						|
  Clearly the three instances of the `HeroBioComponent` can't share the same `HeroCacheService`. 
 | 
						|
  They'd be competing with each other to determine which hero to cache.
 | 
						|
  
 | 
						|
  Each `HeroBioComponent` gets its *own* `HeroCacheService` instance 
 | 
						|
  by listing the `HeroCacheService` in its metadata `providers` array.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bio.component.ts','component','app/hero-bio.component.ts')  
 | 
						|
:marked
 | 
						|
  The parent `HeroBiosComponent` binds a value to the `heroId`.
 | 
						|
  The `ngOnInit` pass that `id` to the service which fetches and caches the hero. 
 | 
						|
  The getter for the `hero` property pulls the cached hero from the service.
 | 
						|
  And the template displays this data-bound property.
 | 
						|
  
 | 
						|
  Find this example in <live-example name="cb-dependency-injection">live code</live-example>
 | 
						|
  and confirm that the three `HeroBioComponent` instances have their own cached hero data. 
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/hero-bios.png" alt="Bios")    
 | 
						|
  
 | 
						|
a(id="optional")
 | 
						|
a(id="qualify-dependency-lookup")
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Qualify dependency lookup with *@Optional* and *@Host*
 | 
						|
  We learned that dependencies can be registered at any level in the component hierarchy. 
 | 
						|
  
 | 
						|
  When a component requests a dependency, Angular starts with that component's injector and walks up the injector tree 
 | 
						|
  until it finds the first suitable provider.  Angular throws an error if it can't find the dependency during that walk. 
 | 
						|
   
 | 
						|
  We *want* this behavior most of the time. 
 | 
						|
  But sometimes we need to limit the search and/or accommodate a missing dependency.
 | 
						|
  We can modify Angular's search behavior with the `@Host` and `@Optional` qualifying decorators,
 | 
						|
  used individually or together.
 | 
						|
  
 | 
						|
  The `@Optional` decorator tells Angular to continue when it can't find the dependency. 
 | 
						|
  Angular sets the injection parameter to `null` instead.
 | 
						|
  
 | 
						|
  The `@Host` decorator stops the upward search at the *host component*. 
 | 
						|
  
 | 
						|
  The host component is typically the component requesting the dependency. 
 | 
						|
  But when this component is projected into a *parent* component, that parent component becomes the host.
 | 
						|
  We look at this second, more interesting case in our next example.
 | 
						|
  
 | 
						|
  ### Demonstration
 | 
						|
  The `HeroBiosAndContactsComponent` is a revision of the `HeroBiosComponent` that we looked at [above](#hero-bios-component).
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','hero-bios-and-contacts','app/hero-bios.component.ts (HeroBiosAndContactsComponent)')
 | 
						|
:marked
 | 
						|
  Focus on the template:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','template')(format='.')
 | 
						|
:marked
 | 
						|
  We've inserted a `<hero-contact>` element between the `<hero-bio>` tags.
 | 
						|
  Angular *projects* (*transcludes*) the corresponding `HeroContactComponent` into the `HeroBioComponent` view, 
 | 
						|
  placing it in the `<ng-content>` slot of the `HeroBioComponent` template:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bio.component.ts','template','app/hero-bio.component.ts (template)')(format='.')
 | 
						|
:marked
 | 
						|
  It looks like this, with the hero's telephone number from `HeroContactComponent` projected above the hero description:
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/hero-bio-and-content.png" alt="bio and contact")    
 | 
						|
:marked
 | 
						|
  Here's the `HeroContactComponent` which demonstrates the qualifying decorators that we're talking about in this section:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-contact.component.ts','component','app/hero-contact.component.ts')
 | 
						|
:marked
 | 
						|
  Focus on the constructor parameters
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-contact.component.ts','ctor-params','app/hero-contact.component.ts')(format='.')
 | 
						|
:marked
 | 
						|
  The `@Host()` function decorating the  `heroCache` property ensures that 
 | 
						|
  we get a reference to the cache service from the parent `HeroBioComponent`.
 | 
						|
  Angular throws if the parent lacks that service, even if a component higher in the component tree happens to have that service.
 | 
						|
  
 | 
						|
  A second `@Host()` function decorates the `loggerService` property.
 | 
						|
  We know the only `LoggerService` instance in the app is provided at the `AppComponent` level.
 | 
						|
  The host `HeroBioComponent` doesn't have its own `LoggerService` provider.
 | 
						|
  
 | 
						|
  Angular would throw an error if we hadn't also decorated the property with the `@Optional()` function.
 | 
						|
  Thanks to `@Optional()`, Angular sets the `loggerService` to null and the rest of the component adapts.
 | 
						|
  
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    We'll come back to the `elementRef` property shortly.
 | 
						|
:marked
 | 
						|
  Here's the `HeroBiosAndContactsComponent` in action.
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/hero-bios-and-contacts.png" alt="Bios with contact into")
 | 
						|
:marked
 | 
						|
  If we comment out the `@Host()` decorator, Angular now walks up the injector ancestor tree 
 | 
						|
  until it finds the logger at the `AppComponent` level. The logger logic kicks in and the hero display updates
 | 
						|
  with the gratuitous "!!!", indicating that the logger was found.
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/hero-bio-contact-no-host.png" alt="Without @Host") 
 | 
						|
:marked
 | 
						|
  On the other hand, if we restore the `@Host()` decorator and comment out `@Optional`, 
 | 
						|
  the application fails for lack of the required logger at the host component level.
 | 
						|
  <br>
 | 
						|
  `EXCEPTION: No provider for LoggerService! (HeroContactComponent -> LoggerService)`
 | 
						|
 | 
						|
<a id="component-element"></a>
 | 
						|
:marked
 | 
						|
  ## Inject the component's element
 | 
						|
  
 | 
						|
  On occasion we might need to access a component's corresponding DOM element. 
 | 
						|
  Although we strive to avoid it, many visual effects and 3rd party tools (such as jQuery)
 | 
						|
  require DOM access. 
 | 
						|
  
 | 
						|
  To illustrate, we've written a simplified version of the `HighlightDirective` from 
 | 
						|
  the [Attribute Directives](../guide/attribute-directives.html) chapter.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/highlight.directive.ts','','app/highlight.directive.ts')
 | 
						|
:marked
 | 
						|
  The directive sets the background to a highlight color when the user mouses over the
 | 
						|
  DOM element to which it is applied.
 | 
						|
  
 | 
						|
  Angular set the constructor's `el` parameter to the injected `ElementRef` which is 
 | 
						|
  a wrapper around that DOM element. 
 | 
						|
  Its `nativeElement` property exposes the DOM element for the directive to manipulate.
 | 
						|
  
 | 
						|
  The sample code applies the directive's `myHighlight` attribute to two `<div>` tags, 
 | 
						|
  first without a value (yielding the default color) and then with an assigned color value.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/app.component.html','highlight','app/app.component.html (highlight)')(format='.')
 | 
						|
:marked
 | 
						|
  The following image shows the effect of mousing over the `<hero-bios-and-contacts>` tag.
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/highlight.png" alt="Highlighted bios")
 | 
						|
:marked
 | 
						|
 | 
						|
<a id="providers"></a>
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Define dependencies with providers
 | 
						|
  
 | 
						|
  In this section we learn to write providers that deliver dependent services.
 | 
						|
  
 | 
						|
  ### Background
 | 
						|
  We get a service from a dependency injector by giving it a ***token***. 
 | 
						|
  
 | 
						|
  We usually let Angular handle this transaction for us by specifying a constructor parameter and its type.
 | 
						|
  The parameter type serves as the injector lookup *token*. 
 | 
						|
  Angular passes this token to the injector and assigns the result to the parameter.
 | 
						|
  Here's a typical example:
 | 
						|
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','ctor','app/hero-bios.component.ts (component constructor injection)')(format='.') 
 | 
						|
:marked
 | 
						|
  Angular asks the injector for the service associated with the `LoggerService` and
 | 
						|
  and assigns the returned value to the `logger` parameter.
 | 
						|
  
 | 
						|
  Where did the injector get that value?
 | 
						|
  It may already have that value in its internal container. 
 | 
						|
  If it doesn't, it may be able to make one with the help of a ***provider***.
 | 
						|
  A *provider* is a recipe for delivering a service associated with a *token*.
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    If the injector doesn't have a provider for the requested *token*, it delegates the request 
 | 
						|
    to its parent injector, where the process repeats until there are no more injectors. 
 | 
						|
    If the search is futile, the injector throws an error ... unless the request was [optional](#optional).
 | 
						|
    
 | 
						|
    Let's return our attention to providers themselves.
 | 
						|
:marked
 | 
						|
  A new injector has no providers.
 | 
						|
  Angular initializes the injectors it creates with some providers it cares about.
 | 
						|
  We have to register our _own_ application providers manually, 
 | 
						|
  usually in the `providers` array of the `Component` or `Directive` metadata:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/app.component.ts','providers','app/app.component.ts (providers)') 
 | 
						|
:marked
 | 
						|
  ### Defining providers
 | 
						|
  
 | 
						|
  The simple class provider is the most typical by far.
 | 
						|
  We mention the class in the `providers` array and we're done.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','class-provider','app/hero-bios.component.ts (class provider)')(format='.') 
 | 
						|
:marked
 | 
						|
  It's that simple because the most common injected service is an instance of a class.
 | 
						|
  But not every dependency can be satisfied by creating a new instance of a class.
 | 
						|
  We need other ways to deliver dependency values and that means we need other ways to specify a provider.
 | 
						|
  
 | 
						|
  The `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why we need them. 
 | 
						|
  
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/hero-of-month.png" alt="Hero of the month" width="300px")
 | 
						|
:marked
 | 
						|
  It's visually simple: a few properties and the output of a logger. The code behind it gives us plenty to talk about.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','hero-of-the-month','hero-of-the-month.component.ts')   
 | 
						|
 | 
						|
.l-main-section
 | 
						|
a(id='provide')
 | 
						|
:marked
 | 
						|
  #### The *provide* object literal
 | 
						|
  
 | 
						|
  The `provide` object literal takes a *token* and a *definition object*.
 | 
						|
  The *token* is usually a class but [it doesn't have to be](#tokens).
 | 
						|
  
 | 
						|
  The *definition* object has one main property, (e.g. `useValue`) that indicates how the provider 
 | 
						|
  should create or return the provided value.
 | 
						|
 | 
						|
.l-main-section
 | 
						|
a(id='usevalue')
 | 
						|
:marked
 | 
						|
  #### useValue - the *value provider*
 | 
						|
  
 | 
						|
  Set the `useValue` property to a ***fixed value*** that the provider can return as the dependency object.
 | 
						|
  
 | 
						|
  Use this technique to provide *runtime configuration constants* such as web-site base addresses and feature flags.
 | 
						|
  We often use a *value provider* in a unit test to replace a production service with a fake or mock.
 | 
						|
  
 | 
						|
  The `HeroOfTheMonthComponent` example has two *value providers*.
 | 
						|
  The first provides an instance of the `Hero` class; 
 | 
						|
  the second specifies a literal string resource:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-value')(format='.')   
 | 
						|
:marked
 | 
						|
  The `Hero` provider token is a class which makes sense because the value is a `Hero`
 | 
						|
  and the consumer of the injected hero would want the type information.
 | 
						|
  
 | 
						|
  The `TITLE` provider token is *not a class*.
 | 
						|
  It's a special kind of provider lookup key called an [OpaqueToken](#opaquetoken).
 | 
						|
  We often use an `OpaqueToken` when the dependency is a simple value like a string, a number, or a function.
 | 
						|
  
 | 
						|
  The value of a *value provider* must be defined *now*. We can't create the value later. 
 | 
						|
  Obviously the title string literal is immediately available. 
 | 
						|
  The `someHero` variable in this example was set earlier in the file:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','some-hero')
 | 
						|
:marked
 | 
						|
  The other providers create their values *lazily* when they're needed for injection.
 | 
						|
 | 
						|
.l-main-section
 | 
						|
a(id='useclass')
 | 
						|
:marked
 | 
						|
  #### useClass - the *class provider*
 | 
						|
  
 | 
						|
  The `useClass` provider creates and returns new instance of the specified class.
 | 
						|
  
 | 
						|
  Use this technique to ***substitute an alternative implementation*** for a common or default class.
 | 
						|
  The alternative could implement a different strategy, extend the default class,
 | 
						|
  or fake the behavior of the real class in a test case.
 | 
						|
  
 | 
						|
  We see two examples in the `HeroOfTheMonthComponent`:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-class')(format='.')   
 | 
						|
:marked
 | 
						|
  The first provider is the *de-sugared*, expanded form of the most typical case in which the
 | 
						|
  class to be created (`HeroService`) is also the provider's injection token. 
 | 
						|
  We wrote it in this long form to de-mystify the preferred short form.
 | 
						|
  
 | 
						|
  The second provider substitutes the `DateLoggerService` for the `LoggerService`.
 | 
						|
  The `LoggerService` is already registered at the `AppComponent` level.
 | 
						|
  When _this component_ requests the `LoggerService`, it receives the `DateLoggerService` instead.
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    This component and its tree of child components receive the `DateLoggerService` instance.
 | 
						|
    Components outside the tree continue to receive the original `LoggerService` instance.
 | 
						|
:marked
 | 
						|
  The `DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:  
 | 
						|
+makeExample('cb-dependency-injection/ts/app/date-logger.service.ts','date-logger-service','app/date-logger.service.ts')(format='.')   
 | 
						|
 | 
						|
.l-main-section
 | 
						|
a(id='useexisting')
 | 
						|
:marked
 | 
						|
  #### useExisting - the *alias provider*
 | 
						|
  
 | 
						|
  The `useExisting` provider maps one token to another. 
 | 
						|
  In effect, the first token is an ***alias*** for the service associated with second token,
 | 
						|
  creating ***two ways to access the same service object***.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-existing')
 | 
						|
:marked
 | 
						|
  Narrowing an API through an aliasing interface is _one_ important use case for this technique.
 | 
						|
  We're aliasing for that very purpose here.
 | 
						|
  Imagine that the `LoggerService` had a large API (it's actually only three methods and a property).
 | 
						|
  We want to shrink that API surface to just the two members exposed by the `MinimalLogger` [*class-interface*](#class-interface):
 | 
						|
 | 
						|
+makeExample('cb-dependency-injection/ts/app/date-logger.service.ts','minimal-logger','app/date-logger.service.ts (MinimalLogger)')(format='.')   
 | 
						|
:marked
 | 
						|
  The constructor's `logger` parameter is typed as `MinimalLogger` so only its two members are visible in TypeScript:
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/minimal-logger-intellisense.png" alt="MinimalLogger restricted API")
 | 
						|
:marked
 | 
						|
  Angular actually sets the `logger` parameter to the injector's full version of the `LoggerService` 
 | 
						|
  which happens to be the `DateLoggerService` thanks to the override provider registered previously via `useClass`.
 | 
						|
  The following image, which displays the logging date, confirms the point:
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/date-logger-entry.png" alt="DateLoggerService entry" width="300px")
 | 
						|
 | 
						|
.l-main-section
 | 
						|
a(id='usefactory')
 | 
						|
:marked
 | 
						|
  #### useFactory - the *factory provider*
 | 
						|
  
 | 
						|
  The `useFactory` provider creates a dependency object by calling a factory function
 | 
						|
  as seen in this example.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-factory')
 | 
						|
:marked
 | 
						|
  Use this technique to ***create a dependency object*** 
 | 
						|
  with a factory function whose inputs are some ***combination of injected services and local state***.
 | 
						|
  
 | 
						|
  The *dependency object* doesn't have to be a class instance. It could be anything.
 | 
						|
  In this example, the *dependency object* is a string of the names of the runners-up
 | 
						|
  to the "Hero of the Month" contest.
 | 
						|
 | 
						|
  The local state is the number `2`, the number of runners-up this component should show.
 | 
						|
  We execute `runnersUpFactory` immediately with `2`. 
 | 
						|
  
 | 
						|
  The `runnersUpFactory` itself isn't the provider factory function.
 | 
						|
  The true provider factory function is the function that `runnersUpFactory` returns.
 | 
						|
  
 | 
						|
+makeExample('cb-dependency-injection/ts/app/runners-up.ts','factory-synopsis','runners-up.ts (excerpt)')(format='.')   
 | 
						|
:marked
 | 
						|
  That returned function takes a winning `Hero` and a `HeroService` as arguments.
 | 
						|
  
 | 
						|
  Angular supplies these arguments from injected values identified by 
 | 
						|
  the two *tokens* in the `deps` array. 
 | 
						|
  The two `deps` values are *tokens* that the injector uses
 | 
						|
  to provide these factory function dependencies.
 | 
						|
  
 | 
						|
  After some undisclosed work, the function returns the string of names 
 | 
						|
  and Angular injects it into the `runnersUp` parameter of the `HeroOfTheMonthComponent`.
 | 
						|
  
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    The function retrieves candidate heroes from the `HeroService`, 
 | 
						|
    takes `2` of them to be the runners-up, and returns their concatenated names.
 | 
						|
    Look at the <live-example name="cb-dependency-injection"></live-example>
 | 
						|
    for the full source code.
 | 
						|
 | 
						|
a(id="tokens")
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Provider token alternatives: the *class-interface* and *OpaqueToken*
 | 
						|
 | 
						|
  Angular dependency injection is easiest when the provider *token* is a class
 | 
						|
  that is also the type of the returned dependency object (what we usually call the *service*).
 | 
						|
  
 | 
						|
  But the token doesn't have to be a class and even when it is a class,
 | 
						|
  it doesn't have to be the same type as the returned object.
 | 
						|
  That's the subject of our next section. 
 | 
						|
  
 | 
						|
  <a id="class-interface"></a>
 | 
						|
  ### class-interface
 | 
						|
  In the previous *Hero of the Month* example, we used the `MinimalLogger` class
 | 
						|
  as the token for a provider of a `LoggerService`.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-existing')
 | 
						|
:marked
 | 
						|
  The `MinimalLogger` is an abstract class. 
 | 
						|
+makeExample('cb-dependency-injection/ts/app/date-logger.service.ts','minimal-logger')(format='.')   
 | 
						|
:marked
 | 
						|
  We usually inherit from an abstract class.
 | 
						|
  But `LoggerService` doesn't inherit from `MinimalLogger`. *No class* inherits from it.
 | 
						|
  Instead, we use it like an interface.
 | 
						|
  
 | 
						|
  Look again at the declaration for `DateLoggerService`
 | 
						|
+makeExample('cb-dependency-injection/ts/app/date-logger.service.ts','date-logger-service-signature')(format='.')   
 | 
						|
:marked
 | 
						|
  `DateLoggerService` inherits (extends) from `LoggerService`, not `MinimalLogger`.
 | 
						|
  The `DateLoggerService` *implements* `MinimalLogger` as if `MinimalLogger` were an *interface*.
 | 
						|
  
 | 
						|
  We call a class used in this way a ***class-interface***.
 | 
						|
  The key benefit of a *class-interface* is that we can get the strong-typing of an interface
 | 
						|
  and we can ***use it as a provider token*** in the same manner as a normal class.
 | 
						|
  
 | 
						|
  A ***class-interface*** should define *only* the members that its consumers are allowed to call.
 | 
						|
  Such a narrowing interface helps decouple the concrete class from its consumers.
 | 
						|
  The `MinimalLogger` defines just two of the `LoggerClass` members.
 | 
						|
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    #### Why *MinimalLogger* is a class and not an interface
 | 
						|
    We can't use an interface as a provider token because 
 | 
						|
    interfaces are not JavaScript objects. 
 | 
						|
    They exist only in the TypeScript design space. 
 | 
						|
    They disappear after the code is transpiled to JavaScript.
 | 
						|
    
 | 
						|
    A provider token must be a real JavaScript object of some kind: 
 | 
						|
    a function, an object, a string ... a class.
 | 
						|
    
 | 
						|
    Using a class as an interface gives us the characteristics of an interface in a JavaScript object.
 | 
						|
    
 | 
						|
    The minimize memory cost, the class should have *no implementation*. 
 | 
						|
    The `MinimalLogger` transpiles to this unoptimized, pre-minified JavaScript:
 | 
						|
  +makeExample('cb-dependency-injection/ts/app/date-logger.service.ts','minimal-logger-transpiled')(format='.')
 | 
						|
  :marked
 | 
						|
     It never grows larger no matter how many members we add *as long as they are typed but not implemented*.
 | 
						|
 | 
						|
a(id='opaque-token')
 | 
						|
:marked
 | 
						|
  ### OpaqueToken
 | 
						|
  
 | 
						|
  Dependency objects can be simple values like dates, numbers and strings or 
 | 
						|
  shapeless objects like arrays and functions.
 | 
						|
  
 | 
						|
  Such objects don't have application interfaces and therefore aren't well represented by a class.
 | 
						|
  They're better represented by a token that is both unique and symbolic, 
 | 
						|
  a JavaScript object that has a friendly name but won't conflict with 
 | 
						|
  another token that happens to have the same name.
 | 
						|
  
 | 
						|
  The `OpaqueToken` has these characteristics.
 | 
						|
  We encountered them twice in the *Hero of the Month* example, 
 | 
						|
  in the *title* value provider and in the *runnersUp* factory provider.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','provide-opaque-token')(format='.')   
 | 
						|
:marked
 | 
						|
  We created the `TITLE` token like this:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','opaque-token')(format='.')   
 | 
						|
 | 
						|
  
 | 
						|
a(id="di-inheritance")
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Inject into a derived class
 | 
						|
  We must take care when writing a component that inherits from another component.
 | 
						|
  If the base component has injected dependencies, 
 | 
						|
  we must re-provide and re-inject them in the derived class
 | 
						|
  and then pass them down to the base class through the constructor.
 | 
						|
  
 | 
						|
  In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent` 
 | 
						|
  to display a *sorted* list of heroes.
 | 
						|
  
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/sorted-heroes.png" alt="Sorted Heroes")
 | 
						|
:marked
 | 
						|
  The `HeroesBaseComponent` could stand on its own.
 | 
						|
  It demands its own instance of the `HeroService` to get heroes
 | 
						|
  and displays them in the order they arrive from the database.
 | 
						|
  
 | 
						|
+makeExample('cb-dependency-injection/ts/app/sorted-heroes.component.ts','heroes-base','app/sorted-heroes.component.ts (HeroesBaseComponent)') 
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    We strongly prefer simple constructors. They should do little more than initialize variables.
 | 
						|
    This rule makes the component safe to construct under test without fear that it will do something dramatic like talk to the server.
 | 
						|
    That's why we call the `HeroService` from within the `ngOnInit` rather than the constructor.
 | 
						|
    
 | 
						|
    We explain the mysterious `afterGetHeroes` below.
 | 
						|
:marked
 | 
						|
  Users want to see the heroes in alphabetical order.
 | 
						|
  Rather than modify the original component, we sub-class it and create a
 | 
						|
  `SortedHeroesComponent` that sorts the heroes before presenting them.
 | 
						|
  The `SortedHeroesComponent` lets the base class fetch the heroes.
 | 
						|
  (we said it was contrived).
 | 
						|
  
 | 
						|
  Unfortunately, Angular cannot inject the `HeroService` directly into the base class.
 | 
						|
  We must provide the `HeroService` again for *this* component, 
 | 
						|
  then pass it down to the base class inside the constructor.
 | 
						|
    
 | 
						|
+makeExample('cb-dependency-injection/ts/app/sorted-heroes.component.ts','sorted-heroes','app/sorted-heroes.component.ts (SortedHeroesComponent)') 
 | 
						|
:marked
 | 
						|
  Now take note of the `afterGetHeroes` method. 
 | 
						|
  Our first instinct was to create an `ngOnInit` method in `SortedHeroesComponent` and do the sorting there.
 | 
						|
  But Angular calls the *derived* class's `ngOnInit` *before* calling the base class's `ngOnInit` 
 | 
						|
  so we'd be sorting the heroes array *before they arrived*. That produces a nasty error.
 | 
						|
  
 | 
						|
  Overriding the base class's `afterGetHeroes` method solves the problem
 | 
						|
  
 | 
						|
  These complications argue for *avoiding component inheritance*. 
 | 
						|
 | 
						|
a(id="find-parent")
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Find a parent component by injection
 | 
						|
  
 | 
						|
  Application components often need to share information.
 | 
						|
  We prefer the more loosely coupled techniques such as data binding and service sharing.
 | 
						|
  But sometimes it makes sense for one component to have a direct reference to another component
 | 
						|
  perhaps to access values or call methods on that component.
 | 
						|
   
 | 
						|
  Obtaining a component reference is a bit tricky in Angular.
 | 
						|
  Although an Angular application is a tree of components,
 | 
						|
  there is no public API for inspecting and traversing that tree. 
 | 
						|
  
 | 
						|
  There is an API for acquiring a child reference
 | 
						|
  (checkout `Query`, `QueryList`, `ViewChildren`, and `ContentChildren`).
 | 
						|
  
 | 
						|
  There is no public API for acquiring a parent reference.
 | 
						|
  But because every component instance is added to an injector's container,
 | 
						|
  we can use Angular dependency injection to reach a parent component.
 | 
						|
  
 | 
						|
  This section describes some techniques for doing that.
 | 
						|
  
 | 
						|
  <a id="known-parent"></a>
 | 
						|
  ### Find a parent component of known type
 | 
						|
  
 | 
						|
  We use standard class injection to acquire a parent component whose type we know.
 | 
						|
  
 | 
						|
  In the following example, the parent `AlexComponent` has several children including a `CathyComponent`:
 | 
						|
a(id='alex')
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-1','parent-finder.component.ts (AlexComponent v.1)')(format='.')
 | 
						|
:marked
 | 
						|
  *Cathy* reports whether or not she has access to *Alex*
 | 
						|
  after injecting an `AlexComponent` into her constructor:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','cathy','parent-finder.component.ts (CathyComponent)')(format='.')
 | 
						|
:marked
 | 
						|
  We added the [@Optional](#optional) qualifier for safety but
 | 
						|
  the <live-example name="cb-dependency-injection"></live-example>
 | 
						|
  confirms that the `alex` parameter is set.
 | 
						|
 | 
						|
  <a id="base-parent"></a>
 | 
						|
  ### Cannot find a parent by its base class
 | 
						|
  
 | 
						|
  What if we do *not* know the concrete parent component class?
 | 
						|
  
 | 
						|
  A re-usable component might be a child of multiple components.
 | 
						|
  Imagine a component for rendering breaking news about a financial instrument.
 | 
						|
  For sound (cough) business reasons, this news component makes frequent calls 
 | 
						|
  directly into its parent instrument as changing market data stream by.
 | 
						|
  
 | 
						|
  The app probably defines more than a dozen financial instrument components.
 | 
						|
  If we're lucky, they all implement the same base class
 | 
						|
  whose API our `NewsComponent` understands.
 | 
						|
  
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    Looking for components that implement an interface would be better.
 | 
						|
    That's not possible because TypeScript interfaces disappear from the transpiled JavaScript
 | 
						|
    which doesn't support interfaces. There's no artifact we could look for.
 | 
						|
:marked
 | 
						|
  We're not claiming this is good design. 
 | 
						|
  We are asking *can a component inject its parent via the parent's base class*?
 | 
						|
  
 | 
						|
  The sample's `CraigComponent` explores this question. [Looking back](#alex) 
 | 
						|
  we see that the `Alex` component *extends* (*inherits*) from a class named `Base`.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-class-signature','parent-finder.component.ts (Alex class signature)')(format='.')
 | 
						|
:marked
 | 
						|
  The `CraigComponent` tries to inject `Base` into its `alex` constructor parameter and reports if it succeeded.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','craig','parent-finder.component.ts (CraigComponent)')(format='.')
 | 
						|
:marked
 | 
						|
  Unfortunately, this does not work. 
 | 
						|
  The <live-example name="cb-dependency-injection"></live-example>
 | 
						|
  confirms that the `alex` parameter is null.
 | 
						|
  *We cannot inject a parent by its base class.*
 | 
						|
  
 | 
						|
  <a id="class-interface-parent"></a>
 | 
						|
  ### Find a parent by its class-interface
 | 
						|
  
 | 
						|
  We can find a parent component with a [class-interface](#class-interface).
 | 
						|
 | 
						|
  The parent must cooperate by providing an *alias* to itself in the name of a *class-interface* token. 
 | 
						|
 | 
						|
  Recall that Angular always adds a component instance to its own injector; 
 | 
						|
  that's why we could inject *Alex* into *Carol* [earlier](#known-parent).
 | 
						|
 | 
						|
  We write an [*alias provider*](#useexisting) — a `provide` object literal with a `useExisting` definition —
 | 
						|
  that creates an *alternative* way to inject the same component instance
 | 
						|
  and add that provider to the `providers` array of the `@Component` metadata for the `AlexComponent`:
 | 
						|
a(id="alex-providers")
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-providers','parent-finder.component.ts (AlexComponent providers)')(format='.')
 | 
						|
:marked
 | 
						|
  [Parent](#parent-token) is the provider's *class-interface* token. 
 | 
						|
  The [*forwardRef*](#forwardref) breaks the circular reference we just created by having the `AlexComponent` refer to itself.
 | 
						|
 | 
						|
  *Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter, the same way we've done it before:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','carol-class','parent-finder.component.ts (CarolComponent class)')(format='.')
 | 
						|
:marked
 | 
						|
  Here's *Alex* and family in action:
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/alex.png" alt="Alex in action")
 | 
						|
  
 | 
						|
a(id="parent-tree")
 | 
						|
:marked
 | 
						|
  ### Find the parent in a tree of parents
 | 
						|
  
 | 
						|
  Imagine one branch of a component hierarchy: *Alice* -> *Barry* -> *Carol*. 
 | 
						|
  Both *Alice* and *Barry* implement the `Parent` *class-interface*.
 | 
						|
  
 | 
						|
  *Barry* is the problem. He needs to reach his parent, *Alice*, and also be a parent to *Carol*.
 | 
						|
  That means he must both *inject* the `Parent` *class-interface* to get *Alice* and
 | 
						|
  *provide* a `Parent` to satisfy *Carol*.
 | 
						|
  
 | 
						|
  Here's *Barry*:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','barry','parent-finder.component.ts (BarryComponent)')(format='.')
 | 
						|
:marked
 | 
						|
  *Barry*'s `providers` array looks just like [*Alex*'s](#alex-providers).
 | 
						|
  If we're going to keep writing [*alias providers*](#useexisting) like this we should create a [helper function](#provideparent).
 | 
						|
  
 | 
						|
  For now, focus on *Barry*'s constructor:
 | 
						|
+makeTabs(
 | 
						|
  'cb-dependency-injection/ts/app/parent-finder.component.ts, cb-dependency-injection/ts/app/parent-finder.component.ts',
 | 
						|
  'barry-ctor, carol-ctor',
 | 
						|
  'Barry\'s constructor, Carol\'s constructor')(format='.')
 | 
						|
:marked
 | 
						|
:marked
 | 
						|
  It's identical to *Carol*'s constructor except for the additional `@SkipSelf` decorator.
 | 
						|
  
 | 
						|
  `@SkipSelf` is essential for two reasons:
 | 
						|
   
 | 
						|
  1. It tell the injector to start its search for a `Parent` dependency in a component *above* itself,
 | 
						|
  which *is* what parent means.
 | 
						|
  
 | 
						|
  2. Angular throws a cyclic dependency error if we omit the `@SkipSelf` decorator.
 | 
						|
  
 | 
						|
    `Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`
 | 
						|
 | 
						|
  Here's *Alice*, *Barry* and family in action:
 | 
						|
 | 
						|
figure.image-display
 | 
						|
  img(src="/resources/images/cookbooks/dependency-injection/alice.png" alt="Alice in action")
 | 
						|
  
 | 
						|
a(id="parent-token")
 | 
						|
:marked
 | 
						|
  ### The *Parent* class-interface
 | 
						|
  We [learned earlier](#class-interface) that a *class-interface* is an abstract class used as an interface rather than as a base class.
 | 
						|
 | 
						|
  Our example defines a `Parent` *class-interface* .
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','parent','parent-finder.component.ts (Parent class-interface)')(format='.')
 | 
						|
:marked
 | 
						|
  The `Parent` *class-interface* defines a `name` property with a type declaration but *no implementation*., 
 | 
						|
  The `name` property is the only member of a parent component that a child component can call.
 | 
						|
  Such a narrowing interface helps decouple the child component class from its parent components.
 | 
						|
  
 | 
						|
  A component that could serve as a parent *should* implement the *class-interface* as the `AliceComponent` does:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alice-class-signature','parent-finder.component.ts (AliceComponent class signature)')(format='.')
 | 
						|
:marked
 | 
						|
  Doing so adds clarity to the code.  But it's not technically necessary. 
 | 
						|
  Although the `AlexComponent` has a `name` property (as required by its `Base` class) 
 | 
						|
  its class signature doesn't mention `Parent`:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-class-signature','parent-finder.component.ts (AlexComponent class signature)')(format='.')
 | 
						|
.l-sub-section
 | 
						|
  :marked
 | 
						|
    The `AlexComponent` *should* implement `Parent` as a matter of proper style. 
 | 
						|
    It doesn't in this example *only* to demonstrate that the code will compile and run without the interface 
 | 
						|
    
 | 
						|
a(id="provideparent")
 | 
						|
:marked
 | 
						|
  ### A *provideParent* helper function
 | 
						|
  
 | 
						|
  Writing variations of the same parent *alias provider* gets old quickly, 
 | 
						|
  especially this awful mouthful with a [*forwardRef*](#forwardref):
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-providers')(format='.')
 | 
						|
:marked
 | 
						|
  We can extract that logic into a helper function like this:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','provide-the-parent')(format='.')
 | 
						|
:marked
 | 
						|
  Now we can add a simpler, more meaningful parent provider to our components:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alice-providers')(format='.')
 | 
						|
:marked
 | 
						|
  We can do better. The current version of the helper function can only alias the `Parent` *class-interface*.
 | 
						|
  Our application might have a variety of parent types, each with its own *class-interface* token.
 | 
						|
  
 | 
						|
  Here's a revised version that defaults to `parent` but also accepts an optional second parameter for a different parent *class-interface*.
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','provide-parent')(format='.')
 | 
						|
:marked
 | 
						|
  And here's how we could use it with a different parent type:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','beth-providers')(format='.')
 | 
						|
:marked
 | 
						|
 | 
						|
a(id="forwardref")
 | 
						|
.l-main-section
 | 
						|
:marked
 | 
						|
  ## Break circularities with a forward class reference (*forwardRef*)
 | 
						|
  
 | 
						|
  The order of class declaration matters in TypeScript.
 | 
						|
  We can't refer directly to a class until it's been defined.
 | 
						|
  
 | 
						|
  This isn't usually a problem, especially if we adhere to the recommended *one class per file* rule.
 | 
						|
  But sometimes circular references are unavoidable. 
 | 
						|
  We're in a bind when class 'A refers to class 'B' and 'B' refers to 'A'.
 | 
						|
  One of them has to be defined first. 
 | 
						|
  
 | 
						|
  The Angular `forwardRef` function creates an *indirect* reference that Angular can resolve later.
 | 
						|
  
 | 
						|
  The *Parent Finder* sample is full of circular class references that are impossible to break.
 | 
						|
  
 | 
						|
:marked
 | 
						|
  We face this dilemma when a class makes *a reference to itself*
 | 
						|
  as does the `AlexComponent` in its `providers` array. 
 | 
						|
  The `providers` array is a property of the `@Component` decorator function which must
 | 
						|
  appear *above* the class definition.
 | 
						|
  
 | 
						|
  We break the circularity with `forwardRef`:
 | 
						|
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-providers','parent-finder.component.ts (AlexComponent providers)')(format='.')
 | 
						|
:marked
 |