docs(dependency-injection): show providers using map literals

This commit is contained in:
Torgeir Helgevold 2016-05-16 21:56:13 -04:00 committed by Ward Bell
parent 7f1412ca97
commit 1644673d6c
9 changed files with 193 additions and 62 deletions

View File

@ -34,11 +34,16 @@ describe('Dependency Injection Cookbook', function () {
expect(sortedHero).toBeDefined(); expect(sortedHero).toBeDefined();
}); });
it('should render Hero of the Month', function () { it('should render Hero of the Month when DI deps are defined using provide()', function () {
var heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0); var heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
expect(heroOfTheMonth).toBeDefined(); expect(heroOfTheMonth).toBeDefined();
}); });
it('should render Hero of the Month when DI deps are defined using provide object literal', function () {
var heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month 2"]')).get(0);
expect(heroOfTheMonth).toBeDefined();
});
it('should render Hero Bios', function () { it('should render Hero Bios', function () {
var heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0); var heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
expect(heroBios).toBeDefined(); expect(heroBios).toBeDefined();
@ -54,8 +59,13 @@ describe('Dependency Injection Cookbook', function () {
expect(magmaPhone).toBeDefined(); expect(magmaPhone).toBeDefined();
}); });
it('should render Hero-of-the-Month runner-ups', function () { it('should render Hero-of-the-Month runner-ups when DI deps are defined using provide()', function () {
var runnersUp = element(by.id('rups')).getText(); var runnersUp = element(by.id('rups1')).getText();
expect(runnersUp).toContain('RubberMan, Mr. Nice');
});
it('should render Hero-of-the-Month runner-ups when DI deps are defined using provide object literal', function () {
var runnersUp = element(by.id('rups2')).getText();
expect(runnersUp).toContain('RubberMan, Mr. Nice'); expect(runnersUp).toContain('RubberMan, Mr. Nice');
}); });

View File

@ -23,6 +23,9 @@
<hero-of-the-month></hero-of-the-month> <hero-of-the-month></hero-of-the-month>
</div> </div>
<div class="di-component">
<hero-of-the-month-lit></hero-of-the-month-lit>
</div>
<div class="di-component"> <div class="di-component">
<h3>Unsorted Heroes</h3> <h3>Unsorted Heroes</h3>

View File

@ -9,10 +9,13 @@ import { HeroesBaseComponent,
import { HighlightDirective } from './highlight.directive'; import { HighlightDirective } from './highlight.directive';
import { ParentFinderComponent } from './parent-finder.component'; import { ParentFinderComponent } from './parent-finder.component';
// Object Literal syntax
import { HeroOfTheMonthLiteralsComponent } from './hero-of-the-month-literals.component';
const DIRECTIVES = [ const DIRECTIVES = [
HeroBiosComponent, HeroBiosAndContactsComponent, HeroBiosComponent, HeroBiosAndContactsComponent,
HeroesBaseComponent, SortedHeroesComponent, HeroesBaseComponent, SortedHeroesComponent,
HeroOfTheMonthComponent, HeroOfTheMonthComponent, HeroOfTheMonthLiteralsComponent,
HighlightDirective, HighlightDirective,
ParentFinderComponent ParentFinderComponent
]; ];
@ -24,7 +27,7 @@ import { UserService } from './user.service';
@Component({ @Component({
selector: 'my-app', selector: 'my-app',
templateUrl:'app/app.component.html', templateUrl: 'app/app.component.html',
directives: DIRECTIVES, directives: DIRECTIVES,
// #docregion providers // #docregion providers
providers: [LoggerService, UserContextService, UserService] providers: [LoggerService, UserContextService, UserService]
@ -33,10 +36,10 @@ import { UserService } from './user.service';
export class AppComponent { export class AppComponent {
// #enddocregion import-services // #enddocregion import-services
private userId:number = 1; private userId: number = 1;
// #docregion ctor // #docregion ctor
constructor(logger:LoggerService, public userContext:UserContextService) { constructor(logger: LoggerService, public userContext: UserContextService) {
userContext.loadUser(this.userId); userContext.loadUser(this.userId);
logger.logInfo('AppComponent initialized'); logger.logInfo('AppComponent initialized');
} }

View File

@ -0,0 +1,67 @@
/* tslint:disable:one-line:check-open-brace*/
// #docplaster
// #docregion opaque-token
import { OpaqueToken } from '@angular/core';
export const TITLE = new OpaqueToken('title');
// #enddocregion opaque-token
// #docregion hero-of-the-month
import { Component, Inject } from '@angular/core';
import { DateLoggerService,
MinimalLogger } from './date-logger.service';
import { Hero } from './hero';
import { HeroService } from './hero.service';
import { LoggerService } from './logger.service';
import { RUNNERS_UP,
runnersUpFactory } from './runners-up';
// #enddocregion hero-of-the-month
// #docregion some-hero
const someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555');
// #enddocregion some-hero
const template = `
<h3>{{title}}</h3>
<div>Winner: <strong>{{heroOfTheMonth.name}}</strong></div>
<div>Reason for award: <strong>{{heroOfTheMonth.description}}</strong></div>
<div>Runners-up: <strong id="rups2">{{runnersUp}}</strong></div>
<p>Logs:</p>
<div id="logs">
<div *ngFor="let log of logs">{{log}}</div>
</div>
`;
// #docregion hero-of-the-month
@Component({
selector: 'hero-of-the-month-lit',
template: template,
// #docregion providers-using-object-literals
providers: [
{provide: Hero, useValue: someHero},
{provide: TITLE, useValue: 'Hero of the Month - Object Literals'},
{provide: HeroService, useClass: HeroService},
{provide: LoggerService, useClass: DateLoggerService},
{provide: MinimalLogger, useExisting: LoggerService},
{provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService]}
]
// #enddocregion providers-using-object-literals
})
export class HeroOfTheMonthLiteralsComponent {
logs: string[] = [];
// #docregion ctor-signature
constructor(
logger: MinimalLogger,
public heroOfTheMonth: Hero,
@Inject(RUNNERS_UP) public runnersUp: string,
@Inject(TITLE) public title: string)
// #enddocregion ctor-signature
{
this.logs = logger.logs;
logger.logInfo('starting up');
}
}
// #enddocregion hero-of-the-month

View File

@ -26,7 +26,7 @@ const template = `
<h3>{{title}}</h3> <h3>{{title}}</h3>
<div>Winner: <strong>{{heroOfTheMonth.name}}</strong></div> <div>Winner: <strong>{{heroOfTheMonth.name}}</strong></div>
<div>Reason for award: <strong>{{heroOfTheMonth.description}}</strong></div> <div>Reason for award: <strong>{{heroOfTheMonth.description}}</strong></div>
<div>Runners-up: <strong id="rups">{{runnersUp}}</strong></div> <div>Runners-up: <strong id="rups1">{{runnersUp}}</strong></div>
<p>Logs:</p> <p>Logs:</p>
<div id="logs"> <div id="logs">

View File

@ -89,6 +89,11 @@ describe('Dependency Injection Tests', function () {
expect(element(by.css('#p3')).getText()).toEqual(expectedMsg); expect(element(by.css('#p3')).getText()).toEqual(expectedMsg);
}); });
it('P3a (provide) displays as expected', function () {
expectedMsg = 'Hello from logger provided with {provide: Logger, useClass: Logger}';
expect(element(by.css('#p3a')).getText()).toEqual(expectedMsg);
});
it('P4 (useClass:BetterLogger) displays as expected', function () { it('P4 (useClass:BetterLogger) displays as expected', function () {
expectedMsg = 'Hello from logger provided with useClass:BetterLogger'; expectedMsg = 'Hello from logger provided with useClass:BetterLogger';
expect(element(by.css('#p4')).getText()).toEqual(expectedMsg); expect(element(by.css('#p4')).getText()).toEqual(expectedMsg);

View File

@ -1,6 +1,7 @@
/* tslint:disable:one-line:check-open-brace*/
// Examples of provider arrays // Examples of provider arrays
//#docplaster // #docplaster
import { Component, Host, Inject, Injectable, import { Component, Inject, Injectable,
provide, Provider } from '@angular/core'; provide, Provider } from '@angular/core';
import { APP_CONFIG, import { APP_CONFIG,
@ -9,7 +10,7 @@ import { APP_CONFIG,
import { HeroService } from './heroes/hero.service'; import { HeroService } from './heroes/hero.service';
import { heroServiceProvider } from './heroes/hero.service.provider'; import { heroServiceProvider } from './heroes/hero.service.provider';
import { Logger } from './logger.service'; import { Logger } from './logger.service';
import { User, UserService } from './user.service'; import { UserService } from './user.service';
let template = '{{log}}'; let template = '{{log}}';
@ -18,12 +19,12 @@ let template = '{{log}}';
selector: 'provider-1', selector: 'provider-1',
template: template, template: template,
providers: providers:
//#docregion providers-1 // #docregion providers-1
[Logger] [Logger]
//#enddocregion providers-1 // #enddocregion providers-1
}) })
export class ProviderComponent1 { export class ProviderComponent1 {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from logger provided with Logger class'); logger.log('Hello from logger provided with Logger class');
this.log = logger.logs[0]; this.log = logger.logs[0];
@ -35,12 +36,12 @@ export class ProviderComponent1 {
selector: 'provider-2', selector: 'provider-2',
template: template, template: template,
providers: providers:
//#docregion providers-2 // #docregion providers-2
[new Provider(Logger, {useClass: Logger})] [new Provider(Logger, {useClass: Logger})]
//#enddocregion providers-2 // #enddocregion providers-2
}) })
export class ProviderComponent2 { export class ProviderComponent2 {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from logger provided with Provider class and useClass'); logger.log('Hello from logger provided with Provider class and useClass');
this.log = logger.logs[0]; this.log = logger.logs[0];
@ -52,18 +53,35 @@ export class ProviderComponent2 {
selector: 'provider-3', selector: 'provider-3',
template: template, template: template,
providers: providers:
//#docregion providers-3 // #docregion providers-3
[provide(Logger, {useClass: Logger})] [provide(Logger, {useClass: Logger})]
//#enddocregion providers-3 // #enddocregion providers-3
}) })
export class ProviderComponent3 { export class ProviderComponent3 {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from logger provided with useClass'); logger.log('Hello from logger provided with useClass');
this.log = logger.logs[0]; this.log = logger.logs[0];
} }
} }
//////////////////////////////////////////
@Component({
selector: 'provider-3a',
template: template,
providers:
// #docregion providers-3a
[{provide: Logger, useClass: Logger}]
// #enddocregion providers-3a
})
export class ProviderComponent3a {
log: string;
constructor(logger: Logger) {
logger.log('Hello from logger provided with {provide: Logger, useClass: Logger}');
this.log = logger.logs[0];
}
}
////////////////////////////////////////// //////////////////////////////////////////
class BetterLogger extends Logger {} class BetterLogger extends Logger {}
@ -71,12 +89,12 @@ class BetterLogger extends Logger {}
selector: 'provider-4', selector: 'provider-4',
template: template, template: template,
providers: providers:
//#docregion providers-4 // #docregion providers-4
[provide(Logger, {useClass: BetterLogger})] [provide(Logger, {useClass: BetterLogger})]
//#enddocregion providers-4 // #enddocregion providers-4
}) })
export class ProviderComponent4 { export class ProviderComponent4 {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from logger provided with useClass:BetterLogger'); logger.log('Hello from logger provided with useClass:BetterLogger');
this.log = logger.logs[0]; this.log = logger.logs[0];
@ -87,11 +105,11 @@ export class ProviderComponent4 {
// #docregion EvenBetterLogger // #docregion EvenBetterLogger
@Injectable() @Injectable()
class EvenBetterLogger { class EvenBetterLogger {
logs:string[] = []; logs: string[] = [];
constructor(private userService: UserService) { } constructor(private userService: UserService) { }
log(message:string){ log(message: string){
message = `Message to ${this.userService.user.name}: ${message}.`; message = `Message to ${this.userService.user.name}: ${message}.`;
console.log(message); console.log(message);
this.logs.push(message); this.logs.push(message);
@ -103,13 +121,13 @@ class EvenBetterLogger {
selector: 'provider-5', selector: 'provider-5',
template: template, template: template,
providers: providers:
//#docregion providers-5 // #docregion providers-5
[ UserService, [ UserService,
provide(Logger, {useClass: EvenBetterLogger}) ] provide(Logger, {useClass: EvenBetterLogger}) ]
//#enddocregion providers-5 // #enddocregion providers-5
}) })
export class ProviderComponent5 { export class ProviderComponent5 {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from EvenBetterlogger'); logger.log('Hello from EvenBetterlogger');
this.log = logger.logs[0]; this.log = logger.logs[0];
@ -119,9 +137,9 @@ export class ProviderComponent5 {
////////////////////////////////////////// //////////////////////////////////////////
class NewLogger extends Logger {} class NewLogger extends Logger {}
class OldLogger { class OldLogger {
logs:string[] = []; logs: string[] = [];
log(message:string) { log(message: string) {
throw new Error('Should not call the old logger!') throw new Error('Should not call the old logger!');
}; };
} }
@ -129,15 +147,15 @@ class OldLogger {
selector: 'provider-6a', selector: 'provider-6a',
template: template, template: template,
providers: providers:
//#docregion providers-6a // #docregion providers-6a
[ NewLogger, [ NewLogger,
// Not aliased! Creates two instances of `NewLogger` // Not aliased! Creates two instances of `NewLogger`
provide(OldLogger, {useClass:NewLogger}) ] provide(OldLogger, {useClass: NewLogger}) ]
//#enddocregion providers-6a // #enddocregion providers-6a
}) })
export class ProviderComponent6a { export class ProviderComponent6a {
log:string; log: string;
constructor(newLogger:NewLogger, oldLogger: OldLogger) { constructor(newLogger: NewLogger, oldLogger: OldLogger) {
if (newLogger === oldLogger){ if (newLogger === oldLogger){
throw new Error('expected the two loggers to be different instances'); throw new Error('expected the two loggers to be different instances');
} }
@ -152,15 +170,15 @@ export class ProviderComponent6a {
selector: 'provider-6b', selector: 'provider-6b',
template: template, template: template,
providers: providers:
//#docregion providers-6b // #docregion providers-6b
[ NewLogger, [ NewLogger,
// Alias OldLogger w/ reference to NewLogger // Alias OldLogger w/ reference to NewLogger
provide(OldLogger, {useExisting: NewLogger}) ] provide(OldLogger, {useExisting: NewLogger}) ]
//#enddocregion providers-6b // #enddocregion providers-6b
}) })
export class ProviderComponent6b { export class ProviderComponent6b {
log:string; log: string;
constructor(newLogger:NewLogger, oldLogger: OldLogger) { constructor(newLogger: NewLogger, oldLogger: OldLogger) {
if (newLogger !== oldLogger){ if (newLogger !== oldLogger){
throw new Error('expected the two loggers to be the same instance'); throw new Error('expected the two loggers to be the same instance');
} }
@ -175,19 +193,19 @@ export class ProviderComponent6b {
let silentLogger = { let silentLogger = {
logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'], logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'],
log: () => {} log: () => {}
} };
// #enddocregion silent-logger // #enddocregion silent-logger
@Component({ @Component({
selector: 'provider-7', selector: 'provider-7',
template: template, template: template,
providers: providers:
//#docregion providers-7 // #docregion providers-7
[provide(Logger, {useValue: silentLogger})] [provide(Logger, {useValue: silentLogger})]
//#enddocregion providers-7 // #enddocregion providers-7
}) })
export class ProviderComponent7 { export class ProviderComponent7 {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from logger provided with useValue'); logger.log('Hello from logger provided with useValue');
this.log = logger.logs[0]; this.log = logger.logs[0];
@ -198,7 +216,7 @@ export class ProviderComponent7 {
@Component({ @Component({
selector: 'provider-8', selector: 'provider-8',
template: template, template: template,
providers:[heroServiceProvider, Logger, UserService] providers: [heroServiceProvider, Logger, UserService]
}) })
export class ProviderComponent8{ export class ProviderComponent8{
// #docregion provider-8-ctor // #docregion provider-8-ctor
@ -206,7 +224,7 @@ export class ProviderComponent8{
// #enddocregion provider-8-ctor // #enddocregion provider-8-ctor
// must be true else this component would have blown up at runtime // must be true else this component would have blown up at runtime
log = 'Hero service injected successfully' log = 'Hero service injected successfully';
} }
///////////////// /////////////////
@ -248,7 +266,7 @@ export class ProviderComponent9a {
selector: 'provider-9b', selector: 'provider-9b',
template: template, template: template,
// #docregion providers-9b // #docregion providers-9b
providers:[provide(APP_CONFIG, {useValue: CONFIG})] providers: [provide(APP_CONFIG, {useValue: CONFIG})]
// #enddocregion providers-9b // #enddocregion providers-9b
}) })
export class ProviderComponent9b { export class ProviderComponent9b {
@ -266,12 +284,12 @@ export class ProviderComponent9b {
@Component({ @Component({
selector: 'provider-10a', selector: 'provider-10a',
template: template, template: template,
//#docregion providers-logger // #docregion providers-logger
providers: [Logger] providers: [Logger]
//#enddocregion providers-logger // #enddocregion providers-logger
}) })
export class ProviderComponent10a { export class ProviderComponent10a {
log:string; log: string;
constructor(logger: Logger) { constructor(logger: Logger) {
logger.log('Hello from the required logger.'); logger.log('Hello from the required logger.');
this.log = logger.logs[0]; this.log = logger.logs[0];
@ -289,8 +307,8 @@ import {Optional} from '@angular/core';
}) })
export class ProviderComponent10b { export class ProviderComponent10b {
// #docregion provider-10-ctor // #docregion provider-10-ctor
log:string; log: string;
constructor(@Optional() private logger:Logger) { } constructor(@Optional() private logger: Logger) { }
// #enddocregion provider-10-ctor // #enddocregion provider-10-ctor
ngOnInit() { ngOnInit() {
@ -298,16 +316,16 @@ export class ProviderComponent10b {
// No logger? Make one! // No logger? Make one!
if (!this.logger) { if (!this.logger) {
this.logger = { this.logger = {
log: (msg:string)=> this.logger.logs.push(msg), log: (msg: string) => this.logger.logs.push(msg),
logs: [] logs: []
} };
// #enddocregion provider-10-logger // #enddocregion provider-10-logger
this.logger.log("Optional logger was not available.") this.logger.log('Optional logger was not available.');
// #docregion provider-10-logger // #docregion provider-10-logger
} }
// #enddocregion provider-10-logger // #enddocregion provider-10-logger
else { else {
this.logger.log('Hello from the injected logger.') this.logger.log('Hello from the injected logger.');
this.log = this.logger.logs[0]; this.log = this.logger.logs[0];
} }
this.log = this.logger.logs[0]; this.log = this.logger.logs[0];
@ -322,6 +340,7 @@ export class ProviderComponent10b {
<div id="p1"><provider-1></provider-1></div> <div id="p1"><provider-1></provider-1></div>
<div id="p2"><provider-2></provider-2></div> <div id="p2"><provider-2></provider-2></div>
<div id="p3"><provider-3></provider-3></div> <div id="p3"><provider-3></provider-3></div>
<div id="p3a"><provider-3a></provider-3a></div>
<div id="p4"><provider-4></provider-4></div> <div id="p4"><provider-4></provider-4></div>
<div id="p5"><provider-5></provider-5></div> <div id="p5"><provider-5></provider-5></div>
<div id="p6a"><provider-6a></provider-6a></div> <div id="p6a"><provider-6a></provider-6a></div>
@ -333,10 +352,11 @@ export class ProviderComponent10b {
<div id="p10a"><provider-10a></provider-10a></div> <div id="p10a"><provider-10a></provider-10a></div>
<div id="p10b"><provider-10b></provider-10b></div> <div id="p10b"><provider-10b></provider-10b></div>
`, `,
directives:[ directives: [
ProviderComponent1, ProviderComponent1,
ProviderComponent2, ProviderComponent2,
ProviderComponent3, ProviderComponent3,
ProviderComponent3a,
ProviderComponent4, ProviderComponent4,
ProviderComponent5, ProviderComponent5,
ProviderComponent6a, ProviderComponent6a,

View File

@ -29,6 +29,8 @@ include ../_util-fns
* [useExisting - the *alias provider*](#useexisting) * [useExisting - the *alias provider*](#useexisting)
* [useFactory - the *factory provider*](#usefactory) * [useFactory - the *factory provider*](#usefactory)
[Define providers with object literals](#object-literals)
[Provider token alternatives](#tokens) [Provider token alternatives](#tokens)
* [class-interface](#class-interface) * [class-interface](#class-interface)
* [OpaqueToken](#opaque-token) * [OpaqueToken](#opaque-token)
@ -541,6 +543,20 @@ a(id='usefactory')
Look at the [live example](/resources/live-examples/cb-dependency-injection/ts/plnkr.html) Look at the [live example](/resources/live-examples/cb-dependency-injection/ts/plnkr.html)
for the full source code. for the full source code.
<a id="object-literals"></a>
.l-main-section
:marked
## Define providers with object literals
:marked
In the previous section we learned to use the `provide` method to customize how dependencies are created.
Instead of calling the `provide` function, we can configure providers with _object literals_.
It's a slightly more concise syntax and we don't have to import the `provide` function.
Here's a set of providers that we saw earlier, re-written with object literals.
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month-literals.component.ts','providers-using-object-literals')(format='.')
a(id="tokens") a(id="tokens")
.l-main-section .l-main-section

View File

@ -569,14 +569,20 @@ code-example(format, language="html").
// #docregion providers-provide-3 // #docregion providers-provide-3
// Skip for Dart, where the provide() function won't pass type checking. // Skip for Dart, where the provide() function won't pass type checking.
:marked :marked
The [provide](../api/core/provide-function.html) function is the more common, friendlier way to create a `Provider`: The [provide](../api/core/provide-function.html) function is the typical way to create a `Provider`:
// #enddocregion providers-provide-3 // #enddocregion providers-provide-3
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-3') +makeExample('dependency-injection/ts/app/providers.component.ts','providers-3')
// #docregion providers-provide-4-1 // #docregion providers-provide-4-1
// Modified for Dart. // Modified for Dart.
:marked :marked
In both approaches &mdash; `Provider` class and `provide` function &mdash; Or we can declare a provider in an _object literal_ and skip the `provide` function.
we supply two arguments. +makeExample('dependency-injection/ts/app/providers.component.ts','providers-3a')
:marked
Pick the syntax that you prefer. They all do the same thing.
In each syntax, we supply two types of values.
// #enddocregion providers-provide-4-1 // #enddocregion providers-provide-4-1
// #docregion providers-provide-4-2 // #docregion providers-provide-4-2
:marked :marked
@ -589,6 +595,7 @@ code-example(format, language="html").
The second is a provider definition object, The second is a provider definition object,
which we can think of as a *recipe* for creating the dependency value. which we can think of as a *recipe* for creating the dependency value.
There are many ways to create dependency values... and many ways to write a recipe. There are many ways to create dependency values... and many ways to write a recipe.
// #docregion providers-alternative-1 // #docregion providers-alternative-1
:marked :marked
<a id="class-provider"></a> <a id="class-provider"></a>
@ -606,7 +613,7 @@ code-example(format, language="html").
This logger gets the user from the injected `UserService`, This logger gets the user from the injected `UserService`,
which happens also to be injected at the application level. which happens also to be injected at the application level.
// #enddocregion providers-alternative-2 // #enddocregion providers-alternative-2
+makeExample('dependency-injection/ts/app/providers.component.ts','EvenBetterLogger') +makeExample('dependency-injection/ts/app/providers.component.ts','EvenBetterLogger')(format='.')
// #docregion providers-alternative-3 // #docregion providers-alternative-3
:marked :marked
Configure it like we did `BetterLogger`. Configure it like we did `BetterLogger`.