angular-cn/aio/dist/generated/docs/guide/dependency-injection-in-action.json

5 lines
54 KiB
JSON

{
"id": "guide/dependency-injection-in-action",
"title": "Dependency injection in action",
"contents": "\n\n\n<div class=\"github-links\">\n <a href=\"https://github.com/angular/angular/edit/master/aio/content/guide/dependency-injection-in-action.md?message=docs%3A%20describe%20your%20change...\" aria-label=\"Suggest Edits\" title=\"Suggest Edits\"><i class=\"material-icons\" aria-hidden=\"true\" role=\"img\">mode_edit</i></a>\n</div>\n\n\n<div class=\"content\">\n <h1 id=\"dependency-injection-in-action\">Dependency injection in action<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#dependency-injection-in-action\"><i class=\"material-icons\">link</i></a></h1>\n<p>This guide explores many of the features of dependency injection (DI) in Angular.</p>\n<div class=\"alert is-helpful\">\n<p>See the <live-example></live-example> for a working example containing the code snippets in this guide.</p>\n</div>\n<a id=\"multiple-service-instances\"></a>\n<h2 id=\"multiple-service-instances-sandboxing\">Multiple service instances (sandboxing)<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#multiple-service-instances-sandboxing\"><i class=\"material-icons\">link</i></a></h2>\n<p>Sometimes you want multiple instances of a service at <em>the same level</em> of the component hierarchy.</p>\n<p>A good example is a service that holds state for its companion component instance.\nYou need a separate instance of the service for each component.\nEach service has its own work-state, isolated from the service-and-state of a different component.\nThis is called <em>sandboxing</em> because each service and component instance has its own sandbox to play in.</p>\n<a id=\"hero-bios-component\"></a>\n<p>In this example, <code>HeroBiosComponent</code> presents three instances of <code>HeroBioComponent</code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-bios.component.ts\" region=\"simple\" header=\"ap/hero-bios.component.ts\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-hero-bios',\n template: `\n &#x3C;app-hero-bio [heroId]=\"1\">&#x3C;/app-hero-bio>\n &#x3C;app-hero-bio [heroId]=\"2\">&#x3C;/app-hero-bio>\n &#x3C;app-hero-bio [heroId]=\"3\">&#x3C;/app-hero-bio>`,\n providers: [HeroService]\n})\nexport class HeroBiosComponent {\n}\n\n</code-example>\n<p>Each <code>HeroBioComponent</code> can edit a single hero's biography.\n<code>HeroBioComponent</code> relies on <code>HeroCacheService</code> to fetch, cache, and perform other persistence operations on that hero.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-cache.service.ts\" region=\"service\" header=\"src/app/hero-cache.service.ts\">\n@<a href=\"api/core/Injectable\" class=\"code-anchor\">Injectable</a>()\nexport class HeroCacheService {\n hero: Hero;\n constructor(private heroService: HeroService) {}\n\n fetchCachedHero(id: number) {\n if (!this.hero) {\n this.hero = this.heroService.getHeroById(id);\n }\n return this.hero;\n }\n}\n\n</code-example>\n<p>Three instances of <code>HeroBioComponent</code> can't share the same instance of <code>HeroCacheService</code>,\nas they'd be competing with each other to determine which hero to cache.</p>\n<p>Instead, each <code>HeroBioComponent</code> gets its <em>own</em> <code>HeroCacheService</code> instance\nby listing <code>HeroCacheService</code> in its metadata <code>providers</code> array.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-bio.component.ts\" region=\"component\" header=\"src/app/hero-bio.component.ts\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-hero-bio',\n template: `\n &#x3C;h4>{{hero.name}}&#x3C;/h4>\n &#x3C;ng-content>&#x3C;/ng-content>\n &#x3C;<a href=\"api/forms/DefaultValueAccessor\" class=\"code-anchor\">textarea</a> cols=\"25\" [(<a href=\"api/forms/NgModel\" class=\"code-anchor\">ngModel</a>)]=\"hero.description\">&#x3C;/<a href=\"api/forms/DefaultValueAccessor\" class=\"code-anchor\">textarea</a>>`,\n providers: [HeroCacheService]\n})\n\nexport class HeroBioComponent implements <a href=\"api/core/OnInit\" class=\"code-anchor\">OnInit</a> {\n @<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>() heroId: number;\n\n constructor(private heroCache: HeroCacheService) { }\n\n ngOnInit() { this.heroCache.fetchCachedHero(this.heroId); }\n\n get hero() { return this.heroCache.hero; }\n}\n\n</code-example>\n<p>The parent <code>HeroBiosComponent</code> binds a value to <code>heroId</code>.\n<code>ngOnInit</code> passes that ID to the service, which fetches and caches the hero.\nThe getter for the <code>hero</code> property pulls the cached hero from the service.\nThe template displays this data-bound property.</p>\n<p>Find this example in <live-example name=\"dependency-injection-in-action\">live code</live-example>\nand confirm that the three <code>HeroBioComponent</code> instances have their own cached hero data.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/hero-bios.png\" alt=\"Bios\" width=\"199\" height=\"317\">\n</div>\n<a id=\"qualify-dependency-lookup\"></a>\n<h2 id=\"qualify-dependency-lookup-with-parameter-decorators\">Qualify dependency lookup with parameter decorators<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#qualify-dependency-lookup-with-parameter-decorators\"><i class=\"material-icons\">link</i></a></h2>\n<p>When a class requires a dependency, that dependency is added to the constructor as a parameter.\nWhen Angular needs to instantiate the class, it calls upon the DI framework to supply the dependency.\nBy default, the DI framework searches for a provider in the injector hierarchy,\nstarting at the component's local injector of the component, and if necessary bubbling up\nthrough the injector tree until it reaches the root injector.</p>\n<ul>\n<li>\n<p>The first injector configured with a provider supplies the dependency (a service instance or value) to the constructor.</p>\n</li>\n<li>\n<p>If no provider is found in the root injector, the DI framework throws an error.</p>\n</li>\n</ul>\n<p>There are a number of options for modifying the default search behavior, using <em>parameter decorators</em>\non the service-valued parameters of a class constructor.</p>\n<a id=\"optional\"></a>\n<h3 id=\"make-a-dependency-optional-and-limit-search-with-host\">Make a dependency <code>@<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a></code> and limit search with <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a></code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#make-a-dependency-optional-and-limit-search-with-host\"><i class=\"material-icons\">link</i></a></h3>\n<p>Dependencies can be registered at any level in the component hierarchy.\nWhen a component requests a dependency, Angular starts with that component's injector\nand walks up the injector tree until it finds the first suitable provider.\nAngular throws an error if it can't find the dependency during that walk.</p>\n<p>In some cases, you need to limit the search or accommodate a missing dependency.\nYou can modify Angular's search behavior with the <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a></code> and <code>@<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a></code> qualifying\ndecorators on a service-valued parameter of the component's constructor.</p>\n<ul>\n<li>\n<p>The <code>@<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a></code> property decorator tells Angular to return null when it can't find the dependency.</p>\n</li>\n<li>\n<p>The <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a></code> property decorator stops the upward search at the <em>host component</em>.\nThe host component is typically the component requesting the dependency.\nHowever, when this component is projected into a <em>parent</em> component,\nthat parent component becomes the host. The following example covers this second case.</p>\n</li>\n</ul>\n<p>These decorators can be used individually or together, as shown in the example.\nThis <code>HeroBiosAndContactsComponent</code> is a revision of <code>HeroBiosComponent</code> which you looked at <a href=\"guide/dependency-injection-in-action#hero-bios-component\">above</a>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-bios.component.ts\" region=\"hero-bios-and-contacts\" header=\"src/app/hero-bios.component.ts (HeroBiosAndContactsComponent)\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-hero-bios-and-contacts',\n template: `\n &#x3C;app-hero-bio [heroId]=\"1\"> &#x3C;app-hero-contact>&#x3C;/app-hero-contact> &#x3C;/app-hero-bio>\n &#x3C;app-hero-bio [heroId]=\"2\"> &#x3C;app-hero-contact>&#x3C;/app-hero-contact> &#x3C;/app-hero-bio>\n &#x3C;app-hero-bio [heroId]=\"3\"> &#x3C;app-hero-contact>&#x3C;/app-hero-contact> &#x3C;/app-hero-bio>`,\n providers: [HeroService]\n})\nexport class HeroBiosAndContactsComponent {\n constructor(logger: LoggerService) {\n logger.logInfo('Creating HeroBiosAndContactsComponent');\n }\n}\n\n</code-example>\n<p>Focus on the template:</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-bios.component.ts\" region=\"template\" header=\"dependency-injection-in-action/src/app/hero-bios.component.ts\">\ntemplate: `\n &#x3C;app-hero-bio [heroId]=\"1\"> &#x3C;app-hero-contact>&#x3C;/app-hero-contact> &#x3C;/app-hero-bio>\n &#x3C;app-hero-bio [heroId]=\"2\"> &#x3C;app-hero-contact>&#x3C;/app-hero-contact> &#x3C;/app-hero-bio>\n &#x3C;app-hero-bio [heroId]=\"3\"> &#x3C;app-hero-contact>&#x3C;/app-hero-contact> &#x3C;/app-hero-bio>`,\n\n</code-example>\n<p>Now there's a new <code>&#x3C;hero-contact></code> element between the <code>&#x3C;hero-bio></code> tags.\nAngular <em>projects</em>, or <em>transcludes</em>, the corresponding <code>HeroContactComponent</code> into the <code>HeroBioComponent</code> view,\nplacing it in the <code>&#x3C;ng-content></code> slot of the <code>HeroBioComponent</code> template.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-bio.component.ts\" region=\"template\" header=\"src/app/hero-bio.component.ts (template)\">\ntemplate: `\n &#x3C;h4>{{hero.name}}&#x3C;/h4>\n &#x3C;ng-content>&#x3C;/ng-content>\n &#x3C;<a href=\"api/forms/DefaultValueAccessor\" class=\"code-anchor\">textarea</a> cols=\"25\" [(<a href=\"api/forms/NgModel\" class=\"code-anchor\">ngModel</a>)]=\"hero.description\">&#x3C;/<a href=\"api/forms/DefaultValueAccessor\" class=\"code-anchor\">textarea</a>>`,\n\n</code-example>\n<p>The result is shown below, with the hero's telephone number from <code>HeroContactComponent</code> projected above the hero description.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/hero-bio-and-content.png\" alt=\"bio and contact\" width=\"199\" height=\"92\">\n</div>\n<p>Here's <code>HeroContactComponent</code>, which demonstrates the qualifying decorators.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-contact.component.ts\" region=\"component\" header=\"src/app/hero-contact.component.ts\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-hero-contact',\n template: `\n &#x3C;div>Phone #: {{phoneNumber}}\n &#x3C;span *<a href=\"api/common/NgIf\" class=\"code-anchor\">ngIf</a>=\"hasLogger\">!!!&#x3C;/span>&#x3C;/div>`\n})\nexport class HeroContactComponent {\n\n hasLogger = false;\n\n constructor(\n @<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>() // limit to the host component's instance of the HeroCacheService\n private heroCache: HeroCacheService,\n\n @<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>() // limit search for logger; hides the application-wide logger\n @<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a>() // ok if the logger doesn't exist\n private loggerService?: LoggerService\n ) {\n if (loggerService) {\n this.hasLogger = true;\n loggerService.logInfo('HeroContactComponent can log!');\n }\n }\n\n get phoneNumber() { return this.heroCache.hero.phone; }\n\n}\n\n</code-example>\n<p>Focus on the constructor parameters.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-contact.component.ts\" region=\"ctor-params\" header=\"src/app/hero-contact.component.ts\">\n@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>() // limit to the host component's instance of the HeroCacheService\nprivate heroCache: HeroCacheService,\n\n@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>() // limit search for logger; hides the application-wide logger\n@<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a>() // ok if the logger doesn't exist\nprivate loggerService?: LoggerService\n\n</code-example>\n<p>The <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>()</code> function decorating the <code>heroCache</code> constructor property ensures that\nyou get a reference to the cache service from the parent <code>HeroBioComponent</code>.\nAngular throws an error if the parent lacks that service, even if a component higher\nin the component tree includes it.</p>\n<p>A second <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>()</code> function decorates the <code>loggerService</code> constructor property.\nThe only <code>LoggerService</code> instance in the app is provided at the <code>AppComponent</code> level.\nThe host <code>HeroBioComponent</code> doesn't have its own <code>LoggerService</code> provider.</p>\n<p>Angular throws an error if you haven't also decorated the property with <code>@<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a>()</code>.\nWhen the property is marked as optional, Angular sets <code>loggerService</code> to null and the rest of the component adapts.</p>\n<p>Here's <code>HeroBiosAndContactsComponent</code> in action.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/hero-bios-and-contacts.png\" alt=\"Bios with contact into\" width=\"206\" height=\"393\">\n</div>\n<p>If you comment out the <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>()</code> decorator, Angular walks up the injector ancestor tree\nuntil it finds the logger at the <code>AppComponent</code> level.\nThe logger logic kicks in and the hero display updates\nwith the \"!!!\" marker to indicate that the logger was found.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/hero-bio-contact-no-host.png\" alt=\"Without @Host\" width=\"199\" height=\"93\">\n</div>\n<p>If you restore the <code>@<a href=\"api/core/Host\" class=\"code-anchor\">Host</a>()</code> decorator and comment out <code>@<a href=\"api/core/Optional\" class=\"code-anchor\">Optional</a></code>,\nthe app throws an exception when it cannot find the required logger at the host component level.</p>\n<p><code>EXCEPTION: No provider for LoggerService! (HeroContactComponent -> LoggerService)</code></p>\n<h3 id=\"supply-a-custom-provider-with-inject\">Supply a custom provider with <code>@<a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a></code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#supply-a-custom-provider-with-inject\"><i class=\"material-icons\">link</i></a></h3>\n<p>Using a custom provider allows you to provide a concrete implementation for implicit dependencies, such as built-in browser APIs. The following example uses an <code><a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a></code> to provide the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage\">localStorage</a> browser API as a dependency in the <code>BrowserStorageService</code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/storage.service.ts\" header=\"src/app/storage.service.ts\">\nimport { <a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a>, <a href=\"api/core/Injectable\" class=\"code-anchor\">Injectable</a>, <a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a> } from '@angular/core';\n\nexport const BROWSER_STORAGE = new <a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a>&#x3C;Storage>('Browser Storage', {\n providedIn: 'root',\n factory: () => localStorage\n});\n\n@<a href=\"api/core/Injectable\" class=\"code-anchor\">Injectable</a>({\n providedIn: 'root'\n})\nexport class BrowserStorageService {\n constructor(@<a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a>(BROWSER_STORAGE) public storage: Storage) {}\n\n get(key: string) {\n return this.storage.getItem(key);\n }\n\n set(key: string, value: string) {\n this.storage.setItem(key, value);\n }\n\n remove(key: string) {\n this.storage.removeItem(key);\n }\n\n clear() {\n this.storage.clear();\n }\n}\n\n\n</code-example>\n<p>The <code>factory</code> function returns the <code>localStorage</code> property that is attached to the browser window object. The <code><a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a></code> decorator is a constructor parameter used to specify a custom provider of a dependency. This custom provider can now be overridden during testing with a mock API of <code>localStorage</code> instead of interacting with real browser APIs.</p>\n<a id=\"skip\"></a>\n<h3 id=\"modify-the-provider-search-with-self-and-skipself\">Modify the provider search with <code>@<a href=\"api/core/Self\" class=\"code-anchor\">Self</a></code> and <code>@<a href=\"api/core/SkipSelf\" class=\"code-anchor\">SkipSelf</a></code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#modify-the-provider-search-with-self-and-skipself\"><i class=\"material-icons\">link</i></a></h3>\n<p>Providers can also be scoped by injector through constructor parameter decorators. The following example overrides the <code>BROWSER_STORAGE</code> token in the <code><a href=\"api/core/Component\" class=\"code-anchor\">Component</a></code> class <code>providers</code> with the <code>sessionStorage</code> browser API. The same <code>BrowserStorageService</code> is injected twice in the constructor, decorated with <code>@<a href=\"api/core/Self\" class=\"code-anchor\">Self</a></code> and <code>@<a href=\"api/core/SkipSelf\" class=\"code-anchor\">SkipSelf</a></code> to define which injector handles the provider dependency.</p>\n<code-example path=\"dependency-injection-in-action/src/app/storage.component.ts\" header=\"src/app/storage.component.ts\">\nimport { <a href=\"api/core/Component\" class=\"code-anchor\">Component</a>, <a href=\"api/core/OnInit\" class=\"code-anchor\">OnInit</a>, <a href=\"api/core/Self\" class=\"code-anchor\">Self</a>, <a href=\"api/core/SkipSelf\" class=\"code-anchor\">SkipSelf</a> } from '@angular/core';\nimport { BROWSER_STORAGE, BrowserStorageService } from './storage.service';\n\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-storage',\n template: `\n Open the inspector to see the local/session storage keys:\n\n &#x3C;h3>Session Storage&#x3C;/h3>\n &#x3C;button (click)=\"setSession()\">Set Session Storage&#x3C;/button>\n\n &#x3C;h3>Local Storage&#x3C;/h3>\n &#x3C;button (click)=\"setLocal()\">Set Local Storage&#x3C;/button>\n `,\n providers: [\n BrowserStorageService,\n { provide: BROWSER_STORAGE, useFactory: () => sessionStorage }\n ]\n})\nexport class StorageComponent implements <a href=\"api/core/OnInit\" class=\"code-anchor\">OnInit</a> {\n\n constructor(\n @<a href=\"api/core/Self\" class=\"code-anchor\">Self</a>() private sessionStorageService: BrowserStorageService,\n @<a href=\"api/core/SkipSelf\" class=\"code-anchor\">SkipSelf</a>() private localStorageService: BrowserStorageService,\n ) { }\n\n ngOnInit() {\n }\n\n setSession() {\n this.sessionStorageService.set('hero', 'Dr Nice - Session');\n }\n\n setLocal() {\n this.localStorageService.set('hero', 'Dr Nice - Local');\n }\n}\n\n\n</code-example>\n<p>Using the <code>@<a href=\"api/core/Self\" class=\"code-anchor\">Self</a></code> decorator, the injector only looks at the component's injector for its providers. The <code>@<a href=\"api/core/SkipSelf\" class=\"code-anchor\">SkipSelf</a></code> decorator allows you to skip the local injector and look up in the hierarchy to find a provider that satisfies this dependency. The <code>sessionStorageService</code> instance interacts with the <code>BrowserStorageService</code> using the <code>sessionStorage</code> browser API, while the <code>localStorageService</code> skips the local injector and uses the root <code>BrowserStorageService</code> that uses the <code>localStorage</code> browser API.</p>\n<a id=\"component-element\"></a>\n<h2 id=\"inject-the-components-dom-element\">Inject the component's DOM element<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#inject-the-components-dom-element\"><i class=\"material-icons\">link</i></a></h2>\n<p>Although developers strive to avoid it, many visual effects and third-party tools, such as jQuery,\nrequire DOM access.\nAs a result, you might need to access a component's DOM element.</p>\n<p>To illustrate, here's a minimal version of <code>HighlightDirective</code> from\nthe <a href=\"guide/attribute-directives\">Attribute Directives</a> page.</p>\n<code-example path=\"dependency-injection-in-action/src/app/highlight.directive.ts\" header=\"src/app/highlight.directive.ts\">\nimport { <a href=\"api/core/Directive\" class=\"code-anchor\">Directive</a>, <a href=\"api/core/ElementRef\" class=\"code-anchor\">ElementRef</a>, <a href=\"api/core/HostListener\" class=\"code-anchor\">HostListener</a>, <a href=\"api/core/Input\" class=\"code-anchor\">Input</a> } from '@angular/core';\n\n@<a href=\"api/core/Directive\" class=\"code-anchor\">Directive</a>({\n selector: '[appHighlight]'\n})\nexport class HighlightDirective {\n\n @<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>('appHighlight') highlightColor: string;\n\n private el: HTMLElement;\n\n constructor(el: <a href=\"api/core/ElementRef\" class=\"code-anchor\">ElementRef</a>) {\n this.el = el.nativeElement;\n }\n\n @<a href=\"api/core/HostListener\" class=\"code-anchor\">HostListener</a>('mouseenter') onMouseEnter() {\n this.highlight(this.highlightColor || 'cyan');\n }\n\n @<a href=\"api/core/HostListener\" class=\"code-anchor\">HostListener</a>('mouseleave') onMouseLeave() {\n this.highlight(null);\n }\n\n private highlight(color: string) {\n this.el.style.backgroundColor = color;\n }\n}\n\n\n</code-example>\n<p>The directive sets the background to a highlight color when the user mouses over the\nDOM element to which the directive is applied.</p>\n<p>Angular sets the constructor's <code>el</code> parameter to the injected <code><a href=\"api/core/ElementRef\" class=\"code-anchor\">ElementRef</a></code>.\n(An <code><a href=\"api/core/ElementRef\" class=\"code-anchor\">ElementRef</a></code> is a wrapper around a DOM element,\nwhose <code>nativeElement</code> property exposes the DOM element for the directive to manipulate.)</p>\n<p>The sample code applies the directive's <code>myHighlight</code> attribute to two <code>&#x3C;div></code> tags,\nfirst without a value (yielding the default color) and then with an assigned color value.</p>\n<code-example path=\"dependency-injection-in-action/src/app/app.component.html\" region=\"highlight\" header=\"src/app/app.component.html (highlight)\">\n&#x3C;div id=\"highlight\" class=\"di-component\" appHighlight>\n &#x3C;h3>Hero Bios and Contacts&#x3C;/h3>\n &#x3C;div appHighlight=\"yellow\">\n &#x3C;app-hero-bios-and-contacts>&#x3C;/app-hero-bios-and-contacts>\n &#x3C;/div>\n&#x3C;/div>\n\n</code-example>\n<p>The following image shows the effect of mousing over the <code>&#x3C;hero-bios-and-contacts></code> tag.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/highlight.png\" alt=\"Highlighted bios\" width=\"318\" height=\"196\">\n</div>\n<a id=\"defining-providers\"></a>\n<h3 id=\"defining-providers\">Defining providers<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#defining-providers\"><i class=\"material-icons\">link</i></a></h3>\n<p>A dependency can't always be created by the default method of instantiating a class.\nYou learned about some other methods in <a href=\"guide/dependency-injection-providers\">Dependency Providers</a>.\nThe following <code>HeroOfTheMonthComponent</code> example demonstrates many of the alternatives and why you need them.\nIt's visually simple: a few properties and the logs produced by a logger.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/hero-of-month.png\" alt=\"Hero of the month\" width=\"300\" height=\"165\">\n</div>\n<p>The code behind it customizes how and where the DI framework provides dependencies.\nThe use cases illustrate different ways to use the <a href=\"guide/dependency-injection-providers#provide\"><em>provide</em> object literal</a> to associate a definition object with a DI token.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"hero-of-the-month\" header=\"hero-of-the-month.component.ts\">\nimport { <a href=\"api/core/Component\" class=\"code-anchor\">Component</a>, <a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a> } from '@angular/core';\n\nimport { DateLoggerService } from './date-logger.service';\nimport { Hero } from './hero';\nimport { HeroService } from './hero.service';\nimport { LoggerService } from './logger.service';\nimport { MinimalLogger } from './minimal-logger.service';\nimport { RUNNERS_UP,\n runnersUpFactory } from './runners-up';\n\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-hero-of-the-month',\n templateUrl: './hero-of-the-month.component.html',\n providers: [\n { provide: Hero, useValue: someHero },\n { provide: TITLE, useValue: 'Hero of the Month' },\n { provide: HeroService, useClass: HeroService },\n { provide: LoggerService, useClass: DateLoggerService },\n { provide: MinimalLogger, useExisting: LoggerService },\n { provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService] }\n ]\n})\nexport class HeroOfTheMonthComponent {\n logs: string[] = [];\n\n constructor(\n logger: MinimalLogger,\n public heroOfTheMonth: Hero,\n @<a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a>(RUNNERS_UP) public runnersUp: string,\n @<a href=\"api/core/Inject\" class=\"code-anchor\">Inject</a>(TITLE) public title: string)\n {\n this.logs = logger.logs;\n logger.logInfo('starting up');\n }\n}\n\n</code-example>\n<p>The <code>providers</code> array shows how you might use the different provider-definition keys;\n<code>useValue</code>, <code>useClass</code>, <code>useExisting</code>, or <code>useFactory</code>.</p>\n<a id=\"usevalue\"></a>\n<h4 id=\"value-providers-usevalue\">Value providers: <code>useValue</code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#value-providers-usevalue\"><i class=\"material-icons\">link</i></a></h4>\n<p>The <code>useValue</code> key lets you associate a fixed value with a DI token.\nUse this technique to provide <em>runtime configuration constants</em> such as website base addresses and feature flags.\nYou can also use a value provider in a unit test to provide mock data in place of a production data service.</p>\n<p>The <code>HeroOfTheMonthComponent</code> example has two value providers.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"use-value\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\n{ provide: Hero, useValue: someHero },\n{ provide: TITLE, useValue: 'Hero of the Month' },\n\n</code-example>\n<ul>\n<li>\n<p>The first provides an existing instance of the <code>Hero</code> class to use for the <code>Hero</code> token, rather than\nrequiring the injector to create a new instance with <code>new</code> or use its own cached instance.\nHere, the token is the class itself.</p>\n</li>\n<li>\n<p>The second specifies a literal string resource to use for the <code>TITLE</code> token.\nThe <code>TITLE</code> provider token is <em>not</em> a class, but is instead a\nspecial kind of provider lookup key called an <a href=\"guide/dependency-injection-in-action#injection-token\">injection token</a>, represented by\nan <code><a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a></code> instance.</p>\n</li>\n</ul>\n<p>You can use an injection token for any kind of provider but it's particularly\nhelpful when the dependency is a simple value like a string, a number, or a function.</p>\n<p>The value of a <em>value provider</em> must be defined before you specify it here.\nThe title string literal is immediately available.\nThe <code>someHero</code> variable in this example was set earlier in the file as shown below.\nYou can't use a variable whose value will be defined later.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"some-hero\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\nconst someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555');\n\n</code-example>\n<p>Other types of providers can create their values <em>lazily</em>; that is, when they're needed for injection.</p>\n<a id=\"useclass\"></a>\n<h4 id=\"class-providers-useclass\">Class providers: <code>useClass</code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#class-providers-useclass\"><i class=\"material-icons\">link</i></a></h4>\n<p>The <code>useClass</code> provider key lets you create and return a new instance of the specified class.</p>\n<p>You can use this type of provider to substitute an <em>alternative implementation</em>\nfor a common or default class.\nThe alternative implementation could, for example, implement a different strategy,\nextend the default class, or emulate the behavior of the real class in a test case.</p>\n<p>The following code shows two examples in <code>HeroOfTheMonthComponent</code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"use-class\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\n{ provide: HeroService, useClass: HeroService },\n{ provide: LoggerService, useClass: DateLoggerService },\n\n</code-example>\n<p>The first provider is the <em>de-sugared</em>, expanded form of the most typical case in which the\nclass to be created (<code>HeroService</code>) is also the provider's dependency injection token.\nThe short form is generally preferred; this long form makes the details explicit.</p>\n<p>The second provider substitutes <code>DateLoggerService</code> for <code>LoggerService</code>.\n<code>LoggerService</code> is already registered at the <code>AppComponent</code> level.\nWhen this child component requests <code>LoggerService</code>, it receives a <code>DateLoggerService</code> instance instead.</p>\n<div class=\"alert is-helpful\">\n<p>This component and its tree of child components receive <code>DateLoggerService</code> instance.\nComponents outside the tree continue to receive the original <code>LoggerService</code> instance.</p>\n</div>\n<p><code>DateLoggerService</code> inherits from <code>LoggerService</code>; it appends the current date/time to each message:</p>\n<code-example path=\"dependency-injection-in-action/src/app/date-logger.service.ts\" region=\"date-logger-service\" header=\"src/app/date-logger.service.ts\">\n@<a href=\"api/core/Injectable\" class=\"code-anchor\">Injectable</a>({\n providedIn: 'root'\n})\nexport class DateLoggerService extends LoggerService\n{\n logInfo(msg: any) { super.logInfo(stamp(msg)); }\n logDebug(msg: any) { super.logInfo(stamp(msg)); }\n logError(msg: any) { super.logError(stamp(msg)); }\n}\n\nfunction stamp(msg: any) { return msg + ' at ' + new Date(); }\n\n</code-example>\n<a id=\"useexisting\"></a>\n<h4 id=\"alias-providers-useexisting\">Alias providers: <code>useExisting</code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#alias-providers-useexisting\"><i class=\"material-icons\">link</i></a></h4>\n<p>The <code>useExisting</code> provider key lets you map one token to another.\nIn effect, the first token is an <em>alias</em> for the service associated with the second token,\ncreating two ways to access the same service object.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"use-existing\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\n{ provide: MinimalLogger, useExisting: LoggerService },\n\n</code-example>\n<p>You can use this technique to narrow an API through an aliasing interface.\nThe following example shows an alias introduced for that purpose.</p>\n<p>Imagine that <code>LoggerService</code> had a large API, much larger than the actual three methods and a property.\nYou might want to shrink that API surface to just the members you actually need.\nIn this example, the <code>MinimalLogger</code> <a href=\"guide/dependency-injection-in-action#class-interface\">class-interface</a> reduces the API to two members:</p>\n<code-example path=\"dependency-injection-in-action/src/app/minimal-logger.service.ts\" header=\"src/app/minimal-logger.service.ts\">\n// Class used as a \"narrowing\" interface that exposes a minimal logger\n// Other members of the actual implementation are invisible\nexport abstract class MinimalLogger {\n logs: string[];\n logInfo: (msg: string) => void;\n}\n\n</code-example>\n<p>The following example puts <code>MinimalLogger</code> to use in a simplified version of <code>HeroOfTheMonthComponent</code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.1.ts\" header=\"src/app/hero-of-the-month.component.ts (minimal version)\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-hero-of-the-month',\n templateUrl: './hero-of-the-month.component.html',\n // TODO: move this aliasing, `useExisting` provider to the AppModule\n providers: [{ provide: MinimalLogger, useExisting: LoggerService }]\n})\nexport class HeroOfTheMonthComponent {\n logs: string[] = [];\n constructor(logger: MinimalLogger) {\n logger.logInfo('starting up');\n }\n}\n\n</code-example>\n<p>The <code>HeroOfTheMonthComponent</code> constructor's <code>logger</code> parameter is typed as <code>MinimalLogger</code>, so only the <code>logs</code> and <code>logInfo</code> members are visible in a TypeScript-aware editor.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/minimal-logger-intellisense.png\" alt=\"MinimalLogger restricted API\" width=\"532\" height=\"60\">\n</div>\n<p>Behind the scenes, Angular sets the <code>logger</code> parameter to the full service registered under the <code>LoggingService</code> token, which happens to be the <code>DateLoggerService</code> instance that was <a href=\"guide/dependency-injection-in-action#useclass\">provided above</a>.</p>\n<div class=\"alert is-helpful\">\n<p>This is illustrated in the following image, which displays the logging date.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/date-logger-entry.png\" alt=\"DateLoggerService entry\" width=\"300\" height=\"32\">\n</div>\n</div>\n<a id=\"usefactory\"></a>\n<h4 id=\"factory-providers-usefactory\">Factory providers: <code>useFactory</code><a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#factory-providers-usefactory\"><i class=\"material-icons\">link</i></a></h4>\n<p>The <code>useFactory</code> provider key lets you create a dependency object by calling a factory function,\nas in the following example.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"use-factory\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\n{ provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService] }\n\n</code-example>\n<p>The injector provides the dependency value by invoking a factory function,\nthat you provide as the value of the <code>useFactory</code> key.\nNotice that this form of provider has a third key, <code>deps</code>, which specifies\ndependencies for the <code>useFactory</code> function.</p>\n<p>Use this technique to create a dependency object with a factory function\nwhose inputs are a combination of <em>injected services</em> and <em>local state</em>.</p>\n<p>The dependency object (returned by the factory function) is typically a class instance,\nbut can be other things as well.\nIn this example, the dependency object is a string of the names of the runners up\nto the \"Hero of the Month\" contest.</p>\n<p>In the example, the local state is the number <code>2</code>, the number of runners up that the component should show.\nThe state value is passed as an argument to <code>runnersUpFactory()</code>.\nThe <code>runnersUpFactory()</code> returns the <em>provider factory function</em>, which can use both\nthe passed-in state value and the injected services <code>Hero</code> and <code>HeroService</code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/runners-up.ts\" region=\"factory-synopsis\" header=\"runners-up.ts (excerpt)\">\nexport function runnersUpFactory(take: number) {\n return (winner: Hero, heroService: HeroService): string => {\n /* ... */\n };\n}\n\n</code-example>\n<p>The provider factory function (returned by <code>runnersUpFactory()</code>) returns the actual dependency object,\nthe string of names.</p>\n<ul>\n<li>\n<p>The function takes a winning <code>Hero</code> and a <code>HeroService</code> as arguments.\nAngular supplies these arguments from injected values identified by\nthe two <em>tokens</em> in the <code>deps</code> array.</p>\n</li>\n<li>\n<p>The function returns the string of names, which Angular than injects into\nthe <code>runnersUp</code> parameter of <code>HeroOfTheMonthComponent</code>.</p>\n</li>\n</ul>\n<div class=\"alert is-helpful\">\n<p>The function retrieves candidate heroes from the <code>HeroService</code>,\ntakes <code>2</code> of them to be the runners-up, and returns their concatenated names.\nLook at the <live-example name=\"dependency-injection-in-action\"></live-example>\nfor the full source code.</p>\n</div>\n<a id=\"tokens\"></a>\n<h2 id=\"provider-token-alternatives-class-interface-and-injectiontoken\">Provider token alternatives: class interface and 'InjectionToken'<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#provider-token-alternatives-class-interface-and-injectiontoken\"><i class=\"material-icons\">link</i></a></h2>\n<p>Angular dependency injection is easiest when the provider token is a class\nthat is also the type of the returned dependency object, or service.</p>\n<p>However, a token doesn't have to be a class and even when it is a class,\nit doesn't have to be the same type as the returned object.\nThat's the subject of the next section.\n<a id=\"class-interface\"></a></p>\n<h3 id=\"class-interface\">Class interface<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#class-interface\"><i class=\"material-icons\">link</i></a></h3>\n<p>The previous <em>Hero of the Month</em> example used the <code>MinimalLogger</code> class\nas the token for a provider of <code>LoggerService</code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"use-existing\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\n{ provide: MinimalLogger, useExisting: LoggerService },\n\n</code-example>\n<p><code>MinimalLogger</code> is an abstract class.</p>\n<code-example path=\"dependency-injection-in-action/src/app/minimal-logger.service.ts\" header=\"dependency-injection-in-action/src/app/minimal-logger.service.ts\">\n// Class used as a \"narrowing\" interface that exposes a minimal logger\n// Other members of the actual implementation are invisible\nexport abstract class MinimalLogger {\n logs: string[];\n logInfo: (msg: string) => void;\n}\n\n</code-example>\n<p>An abstract class is usually a base class that you can extend.\nIn this app, however there is no class that inherits from <code>MinimalLogger</code>.\nThe <code>LoggerService</code> and the <code>DateLoggerService</code> could have inherited from <code>MinimalLogger</code>,\nor they could have implemented it instead, in the manner of an interface.\nBut they did neither.\n<code>MinimalLogger</code> is used only as a dependency injection token.</p>\n<p>When you use a class this way, it's called a <em>class interface</em>.</p>\n<p>As mentioned in <a href=\"guide/dependency-injection-providers#di-and-interfaces\">DI Providers</a>,\nan interface is not a valid DI token because it is a TypeScript artifact that doesn't exist at run time.\nUse this abstract class interface to get the strong typing of an interface,\nand also use it as a provider token in the way you would a normal class.</p>\n<p>A class interface should define <em>only</em> the members that its consumers are allowed to call.\nSuch a narrowing interface helps decouple the concrete class from its consumers.</p>\n<div class=\"alert is-helpful\">\n<p>Using a class as an interface gives you the characteristics of an interface in a real JavaScript object.\nTo minimize memory cost, however, the class should have <em>no implementation</em>.\nThe <code>MinimalLogger</code> transpiles to this unoptimized, pre-minified JavaScript for a constructor function.</p>\n<code-example path=\"dependency-injection-in-action/src/app/minimal-logger.service.ts\" region=\"minimal-logger-transpiled\" header=\"dependency-injection-in-action/src/app/minimal-logger.service.ts\">\nvar MinimalLogger = (function () {\n function MinimalLogger() {}\n return MinimalLogger;\n}());\nexports(\"MinimalLogger\", MinimalLogger);\n\n</code-example>\n<p>Notice that it doesn't have any members. It never grows no matter how many members you add to the class,\nas long as those members are typed but not implemented.</p>\n<p>Look again at the TypeScript <code>MinimalLogger</code> class to confirm that it has no implementation.</p>\n</div>\n<a id=\"injection-token\"></a>\n<h3 id=\"injectiontoken-objects\">'InjectionToken' objects<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#injectiontoken-objects\"><i class=\"material-icons\">link</i></a></h3>\n<p>Dependency objects can be simple values like dates, numbers and strings, or\nshapeless objects like arrays and functions.</p>\n<p>Such objects don't have application interfaces and therefore aren't well represented by a class.\nThey're better represented by a token that is both unique and symbolic,\na JavaScript object that has a friendly name but won't conflict with\nanother token that happens to have the same name.</p>\n<p><code><a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a></code> has these characteristics.\nYou encountered them twice in the <em>Hero of the Month</em> example,\nin the <em>title</em> value provider and in the <em>runnersUp</em> factory provider.</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"provide-injection-token\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\n{ provide: TITLE, useValue: 'Hero of the Month' },\n{ provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService] }\n\n</code-example>\n<p>You created the <code>TITLE</code> token like this:</p>\n<code-example path=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\" region=\"injection-token\" header=\"dependency-injection-in-action/src/app/hero-of-the-month.component.ts\">\nimport { <a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a> } from '@angular/core';\n\nexport const TITLE = new <a href=\"api/core/InjectionToken\" class=\"code-anchor\">InjectionToken</a>&#x3C;string>('title');\n\n</code-example>\n<p>The type parameter, while optional, conveys the dependency's type to developers and tooling.\nThe token description is another developer aid.</p>\n<a id=\"di-inheritance\"></a>\n<h2 id=\"inject-into-a-derived-class\">Inject into a derived class<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#inject-into-a-derived-class\"><i class=\"material-icons\">link</i></a></h2>\n<p>Take care when writing a component that inherits from another component.\nIf the base component has injected dependencies,\nyou must re-provide and re-inject them in the derived class\nand then pass them down to the base class through the constructor.</p>\n<p>In this contrived example, <code>SortedHeroesComponent</code> inherits from <code>HeroesBaseComponent</code>\nto display a <em>sorted</em> list of heroes.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/dependency-injection-in-action/sorted-heroes.png\" alt=\"Sorted Heroes\" width=\"135\" height=\"107\">\n</div>\n<p>The <code>HeroesBaseComponent</code> can stand on its own.\nIt demands its own instance of <code>HeroService</code> to get heroes\nand displays them in the order they arrive from the database.</p>\n<code-example path=\"dependency-injection-in-action/src/app/sorted-heroes.component.ts\" region=\"heroes-base\" header=\"src/app/sorted-heroes.component.ts (HeroesBaseComponent)\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-unsorted-heroes',\n template: `&#x3C;div *<a href=\"api/common/NgForOf\" class=\"code-anchor\">ngFor</a>=\"let hero of heroes\">{{hero.name}}&#x3C;/div>`,\n providers: [HeroService]\n})\nexport class HeroesBaseComponent implements <a href=\"api/core/OnInit\" class=\"code-anchor\">OnInit</a> {\n constructor(private heroService: HeroService) { }\n\n heroes: Array&#x3C;Hero>;\n\n ngOnInit() {\n this.heroes = this.heroService.getAllHeroes();\n this.afterGetHeroes();\n }\n\n // Post-process heroes in derived class override.\n protected afterGetHeroes() {}\n\n}\n\n</code-example>\n<div class=\"alert is-helpful\">\n<h3 id=\"keep-constructors-simple\">Keep constructors simple<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#keep-constructors-simple\"><i class=\"material-icons\">link</i></a></h3>\n<p>Constructors should do little more than initialize variables.\nThis rule makes the component safe to construct under test without fear that it will do something dramatic like talk to the server.\nThat's why you call the <code>HeroService</code> from within the <code>ngOnInit</code> rather than the constructor.</p>\n</div>\n<p>Users want to see the heroes in alphabetical order.\nRather than modify the original component, sub-class it and create a\n<code>SortedHeroesComponent</code> that sorts the heroes before presenting them.\nThe <code>SortedHeroesComponent</code> lets the base class fetch the heroes.</p>\n<p>Unfortunately, Angular cannot inject the <code>HeroService</code> directly into the base class.\nYou must provide the <code>HeroService</code> again for <em>this</em> component,\nthen pass it down to the base class inside the constructor.</p>\n<code-example path=\"dependency-injection-in-action/src/app/sorted-heroes.component.ts\" region=\"sorted-heroes\" header=\"src/app/sorted-heroes.component.ts (SortedHeroesComponent)\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-sorted-heroes',\n template: `&#x3C;div *<a href=\"api/common/NgForOf\" class=\"code-anchor\">ngFor</a>=\"let hero of heroes\">{{hero.name}}&#x3C;/div>`,\n providers: [HeroService]\n})\nexport class SortedHeroesComponent extends HeroesBaseComponent {\n constructor(heroService: HeroService) {\n super(heroService);\n }\n\n protected afterGetHeroes() {\n this.heroes = this.heroes.sort((h1, h2) => {\n return h1.name &#x3C; h2.name ? -1 :\n (h1.name > h2.name ? 1 : 0);\n });\n }\n}\n\n</code-example>\n<p>Now take note of the <code>afterGetHeroes()</code> method.\nYour first instinct might have been to create an <code>ngOnInit</code> method in <code>SortedHeroesComponent</code> and do the sorting there.\nBut Angular calls the <em>derived</em> class's <code>ngOnInit</code> <em>before</em> calling the base class's <code>ngOnInit</code>\nso you'd be sorting the heroes array <em>before they arrived</em>. That produces a nasty error.</p>\n<p>Overriding the base class's <code>afterGetHeroes()</code> method solves the problem.</p>\n<p>These complications argue for <em>avoiding component inheritance</em>.</p>\n<a id=\"forwardref\"></a>\n<h2 id=\"break-circularities-with-a-forward-class-reference-forwardref\">Break circularities with a forward class reference (<em>forwardRef</em>)<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/dependency-injection-in-action#break-circularities-with-a-forward-class-reference-forwardref\"><i class=\"material-icons\">link</i></a></h2>\n<p>The order of class declaration matters in TypeScript.\nYou can't refer directly to a class until it's been defined.</p>\n<p>This isn't usually a problem, especially if you adhere to the recommended <em>one class per file</em> rule.\nBut sometimes circular references are unavoidable.\nYou're in a bind when class 'A' refers to class 'B' and 'B' refers to 'A'.\nOne of them has to be defined first.</p>\n<p>The Angular <code><a href=\"api/core/forwardRef\" class=\"code-anchor\">forwardRef</a>()</code> function creates an <em>indirect</em> reference that Angular can resolve later.</p>\n<p>The <em>Parent Finder</em> sample is full of circular class references that are impossible to break.</p>\n<p>You face this dilemma when a class makes <em>a reference to itself</em>\nas does <code>AlexComponent</code> in its <code>providers</code> array.\nThe <code>providers</code> array is a property of the <code>@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>()</code> decorator function which must\nappear <em>above</em> the class definition.</p>\n<p>Break the circularity with <code><a href=\"api/core/forwardRef\" class=\"code-anchor\">forwardRef</a></code>.</p>\n<code-example path=\"dependency-injection-in-action/src/app/parent-finder.component.ts\" region=\"alex-providers\" header=\"parent-finder.component.ts (AlexComponent providers)\">\nproviders: [{ provide: Parent, useExisting: <a href=\"api/core/forwardRef\" class=\"code-anchor\">forwardRef</a>(() => AlexComponent) }],\n\n</code-example>\n\n \n</div>\n\n<!-- links to this doc:\n - api/core/Host\n - api/core/SkipSelf\n - errors/NG0200\n - guide/dependency-injection\n - guide/dependency-injection-navtree\n - guide/dependency-injection-providers\n - guide/hierarchical-dependency-injection\n-->\n<!-- links from this doc:\n - api/common/NgForOf\n - api/common/NgIf\n - api/core/Component\n - api/core/Directive\n - api/core/ElementRef\n - api/core/Host\n - api/core/HostListener\n - api/core/Inject\n - api/core/Injectable\n - api/core/InjectionToken\n - api/core/Input\n - api/core/OnInit\n - api/core/Optional\n - api/core/Self\n - api/core/SkipSelf\n - api/core/forwardRef\n - api/forms/DefaultValueAccessor\n - api/forms/NgModel\n - guide/attribute-directives\n - guide/dependency-injection-in-action#alias-providers-useexisting\n - guide/dependency-injection-in-action#break-circularities-with-a-forward-class-reference-forwardref\n - guide/dependency-injection-in-action#class-interface\n - guide/dependency-injection-in-action#class-providers-useclass\n - guide/dependency-injection-in-action#defining-providers\n - guide/dependency-injection-in-action#dependency-injection-in-action\n - guide/dependency-injection-in-action#factory-providers-usefactory\n - guide/dependency-injection-in-action#hero-bios-component\n - guide/dependency-injection-in-action#inject-into-a-derived-class\n - guide/dependency-injection-in-action#inject-the-components-dom-element\n - guide/dependency-injection-in-action#injection-token\n - guide/dependency-injection-in-action#injectiontoken-objects\n - guide/dependency-injection-in-action#keep-constructors-simple\n - guide/dependency-injection-in-action#make-a-dependency-optional-and-limit-search-with-host\n - guide/dependency-injection-in-action#modify-the-provider-search-with-self-and-skipself\n - guide/dependency-injection-in-action#multiple-service-instances-sandboxing\n - guide/dependency-injection-in-action#provider-token-alternatives-class-interface-and-injectiontoken\n - guide/dependency-injection-in-action#qualify-dependency-lookup-with-parameter-decorators\n - guide/dependency-injection-in-action#supply-a-custom-provider-with-inject\n - guide/dependency-injection-in-action#useclass\n - guide/dependency-injection-in-action#value-providers-usevalue\n - guide/dependency-injection-providers\n - guide/dependency-injection-providers#di-and-interfaces\n - guide/dependency-injection-providers#provide\n - https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage\n - https://github.com/angular/angular/edit/master/aio/content/guide/dependency-injection-in-action.md?message=docs%3A%20describe%20your%20change...\n-->"
}