Skip to content

Commit c489b17

Browse files
committed
docs(dependency-injection): revised Dart and TS code and prose
Contributes to angular#1508 and angular#1522. - The main change on the TS side is to present best practices first, rather than presenting sample code and then saying "don't do that". - The "Optional dependencies" section has been moved towards the end of the provider variants section and its sample code has been simplified. - Reworked *_1.{ts,dart} sources so that main_1.{ts,dart} can actually be run, which helped find some bugs in those sources. - Despite angular/angular#8928, the Dart and TS OpaqueToken sections have been left in the prose. They can be revisited later. Enhancements to the Dart code include: - Added TestComponent. - Added a provider sample that makes use of an app config Map (to match TS); also added the more Dart-like use of a custom app configuration class, whose instance is initialized via the cascade operator. - Fixed Engine class hierarchy so that a single field named `cylinders` is defined (rather than two fields: one in the Engine supertype and one in the subclass), because having two fields is a bad design smell. - Similarly, fixed Logger hierarchy so that a single field named `logs` is defined. Also made `logs` a read-only field. - Reintroduced the SilentLogger().
1 parent 7570dc5 commit c489b17

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1025
-1279
lines changed

public/docs/_examples/dependency-injection/dart/example-config.json

Whitespace-only changes.

public/docs/_examples/dependency-injection/dart/lib/app_component.dart

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'user_service.dart';
1111
//PENDING: check whether we intend to hide injector_component.dart & providers_component.dart; if so, change docregion name?
1212
// #enddocregion imports
1313
import 'injector_component.dart';
14+
import 'test_component.dart';
1415
import 'providers_component.dart';
1516

1617
@Component(
@@ -31,21 +32,21 @@ import 'providers_component.dart';
3132
CarComponent,
3233
HeroesComponent,
3334
InjectorComponent,
35+
TestComponent,
3436
ProvidersComponent
3537
],
36-
// #docregion providers
38+
// #docregion providers
3739
providers: const [
38-
Logger,
39-
UserService,
40-
const Provider(AppConfig, useValue: config1)]
41-
// #enddocregion providers
40+
Logger, UserService,
41+
const Provider(APP_CONFIG, useFactory: heroDiConfigFactory)]
42+
// #enddocregion providers
4243
)
4344
class AppComponent {
4445
final UserService _userService;
4546
final String title;
4647

47-
//#docregion ctor
48-
AppComponent(AppConfig config, this._userService)
48+
// #docregion ctor
49+
AppComponent(@Inject(APP_CONFIG) AppConfig config, this._userService)
4950
: title = config.title;
5051
// #enddocregion ctor
5152

@@ -64,4 +65,3 @@ class AppComponent {
6465
String get userInfo => 'Current user, ${user.name}, is'
6566
'${isAuthorized ? "" : " not"} authorized. ';
6667
}
67-
// #enddocregion

public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart

-10
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,3 @@ import 'heroes/heroes_component_1.dart';
1616
class AppComponent {
1717
final String title = 'Dependency Injection';
1818
}
19-
// #enddocregion
20-
21-
/*
22-
//#docregion ctor-di-fail
23-
// FAIL! Injectable `config` is not a class!
24-
AppComponent(HeroService heroService, Map config) {
25-
title = config['title'];
26-
}
27-
//#enddocregion ctor-di-fail
28-
*/

public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart

+8-5
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ import 'logger_service.dart';
2121
],
2222
providers: const [
2323
Logger,
24-
const Provider(AppConfig, useValue: config1)
25-
])
24+
// #docregion providers
25+
const Provider(APP_CONFIG, useValue: heroDiConfig)
26+
// #enddocregion providers
27+
]
28+
)
2629
class AppComponent {
2730
final String title;
2831

2932
// #docregion ctor
30-
AppComponent(AppConfig config)
31-
: title = config.title;
32-
// #enddocregion
33+
AppComponent(@Inject(APP_CONFIG) Map config)
34+
: title = config['title'];
35+
// #enddocregion ctor
3336
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
1-
// #docregion
21
// #docregion token
32
import 'package:angular2/core.dart';
43

5-
//#docregion const-class
6-
@Injectable()
7-
class AppConfig {
8-
final apiEndpoint;
9-
final String title;
4+
const APP_CONFIG = const OpaqueToken('app.config');
5+
// #enddocregion token
6+
7+
// #docregion config
8+
const Map heroDiConfig = const <String,String>{
9+
'apiEndpoint' : 'api.heroes.com',
10+
'title' : 'Dependency Injection'
11+
};
12+
// #enddocregion config
1013

11-
const AppConfig(this.apiEndpoint, this.title);
14+
// #docregion config-alt
15+
class AppConfig {
16+
String apiEndpoint;
17+
String title;
1218
}
13-
//#enddocregion const-class
1419

15-
//#docregion const-object
16-
const config1 = const AppConfig('api.heroes.com', 'Dependency Injection');
17-
//#enddocregion const-object
20+
AppConfig heroDiConfigFactory() => new AppConfig()
21+
..apiEndpoint = 'api.heroes.com'
22+
..title = 'Dependency Injection';
23+
// #enddocregion config-alt
24+
25+
const appConfigProvider = const Provider(APP_CONFIG,
26+
useFactory: heroDiConfigFactory,
27+
deps: const []);
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
// #docregion
21
import 'package:angular2/core.dart';
32

43
@Injectable()
5-
// #docregion engine
64
class Engine {
7-
final int cylinders = 4;
5+
final int cylinders;
6+
7+
Engine() : cylinders = 4;
8+
Engine.withCylinders(this.cylinders);
89
}
9-
// #enddocregion engine
1010

1111
@Injectable()
12-
// #docregion tires
1312
class Tires {
1413
String make = 'Flintstone';
1514
String model = 'Square';
1615
}
1716

18-
// #enddocregion tires
1917
@Injectable()
2018
class Car {
2119
//#docregion car-ctor
@@ -24,11 +22,10 @@ class Car {
2422
String description = 'DI';
2523

2624
Car(this.engine, this.tires);
27-
2825
// #enddocregion car-ctor
2926

3027
// Method using the engine and tires
31-
String drive() => '$description car with ${engine.cylinders} cylinders'
32-
' and ${tires.make} tires.';
28+
String drive() => '$description car with '
29+
'${engine.cylinders} cylinders and '
30+
'${tires.make} tires.';
3331
}
34-
// #enddocregion car

public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart

+24-35
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,39 @@
33
import 'car.dart';
44

55
///////// example 1 ////////////
6-
Car simpleCar() {
7-
//#docregion car-ctor-instantiation
6+
Car simpleCar() =>
7+
// #docregion car-ctor-instantiation
88
// Simple car with 4 cylinders and Flintstone tires.
9-
var car = new Car(new Engine(), new Tires());
10-
//#enddocregion car-ctor-instantiation
11-
car.description = 'Simple';
12-
return car;
13-
}
14-
///////// example 2 ////////////
9+
new Car(new Engine(), new Tires())
10+
// #enddocregion car-ctor-instantiation
11+
..description = 'Simple';
1512

16-
//#docregion car-ctor-instantiation-with-param
17-
class Engine2 implements Engine {
18-
final int cylinders;
13+
///////// example 2 ////////////
1914
20-
Engine2(this.cylinders);
21-
}
22-
//#enddocregion car-ctor-instantiation-with-param
23-
24-
Car superCar() {
25-
//#docregion car-ctor-instantiation-with-param
26-
// Super car with 12 cylinders and Flintstone tires.
27-
var bigCylinders = 12;
28-
var car = new Car(new Engine2(bigCylinders), new Tires());
29-
//#enddocregion car-ctor-instantiation-with-param
30-
car.description = 'Super';
31-
return car;
15+
// #docregion car-ctor-instantiation-with-param
16+
class Engine2 extends Engine {
17+
Engine2(cylinders) : super.withCylinders(cylinders);
3218
}
19+
20+
Car superCar() =>
21+
// Super car with 12 cylinders and Flintstone tires.
22+
new Car(new Engine2(12), new Tires())
23+
..description = 'Super';
24+
// #enddocregion car-ctor-instantiation-with-param
25+
3326
/////////// example 3 //////////
3427
35-
//#docregion car-ctor-instantiation-with-mocks
28+
// #docregion car-ctor-instantiation-with-mocks
3629
class MockEngine extends Engine {
37-
final int cylinders = 8;
30+
MockEngine() : super.withCylinders(8);
3831
}
3932

4033
class MockTires extends Tires {
41-
String make = 'YokoGoodStone';
34+
MockTires() { make = 'YokoGoodStone'; }
4235
}
4336

44-
//#enddocregion car-ctor-instantiation-with-mocks
45-
Car testCar() {
46-
//#docregion car-ctor-instantiation-with-mocks
47-
// Test car with 8 cylinders and YokoGoodStone tires.
48-
var car = new Car(new MockEngine(), new MockTires());
49-
//#enddocregion car-ctor-instantiation-with-mocks
50-
car.description = 'Test';
51-
return car;
52-
}
37+
Car testCar() =>
38+
// Test car with 8 cylinders and YokoGoodStone tires.
39+
new Car(new MockEngine(), new MockTires())
40+
..description = 'Test';
41+
// #enddocregion car-ctor-instantiation-with-mocks

public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ import 'car.dart';
33

44
// BAD pattern!
55
class CarFactory {
6-
Car createCar() {
7-
return new Car(createEngine(), createTires())
8-
..description = 'Factory';
9-
}
6+
Car createCar() =>
7+
new Car(createEngine(), createTires())
8+
..description = 'Factory';
109

1110
Engine createEngine() => new Engine();
1211
Tires createTires() => new Tires();
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,27 @@
1-
// #docplaster
2-
//#docregion
31
import 'package:angular2/core.dart';
42

53
import '../logger_service.dart';
64
import 'car.dart';
75

8-
//#docregion injector
6+
// #docregion injector
97
Car useInjector() {
108
ReflectiveInjector injector;
11-
//#enddocregion injector
12-
9+
// #enddocregion injector
1310
/*
14-
//#docregion injector-no-new
15-
// Cannot 'new' an ReflectiveInjector like this!
16-
var injector = new ReflectiveInjector([Car, Engine, Tires, Logger]);
17-
//#enddocregion injector-no-new
18-
*/
19-
20-
//#docregion injector
21-
22-
//#docregion injector-create-and-call
23-
injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires, Logger]);
24-
//#docregion injector-call
11+
// #docregion injector-no-new
12+
// Cannot instantiate an ReflectiveInjector like this!
13+
var injector = new ReflectiveInjector([Car, Engine, Tires]);
14+
// #enddocregion injector-no-new
15+
*/
16+
// #docregion injector, injector-create-and-call
17+
injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
18+
// #docregion injector-call
2519
var car = injector.get(Car);
26-
//#enddocregion injector-call
27-
//#enddocregion injector-create-and-call
28-
20+
// #enddocregion injector-call, injector-create-and-call
2921
car.description = 'Injector';
22+
23+
injector = ReflectiveInjector.resolveAndCreate([Logger]);
3024
var logger = injector.get(Logger);
3125
logger.log('Injector car.drive() said: ' + car.drive());
3226
return car;
3327
}
34-
//#enddocregion injector
35-
36-
//#enddocregion

public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Car {
1717

1818
// Method using the engine and tires
1919
String drive() => '$description car with '
20-
'${engine.cylinders} cylinders and ${tires.make} tires.';
20+
'${engine.cylinders} cylinders and '
21+
'${tires.make} tires.';
2122
}
2223
//#enddocregion car
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// #docregion
22
class Hero {
3-
num id;
4-
String name;
5-
bool isSecret = false;
3+
final int id;
4+
final String name;
5+
final bool isSecret;
6+
7+
Hero(this.id, this.name, [this.isSecret = false]);
68
}

public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import 'hero_service.dart';
1414
class HeroListComponent {
1515
final List<Hero> heroes;
1616

17-
//#docregion ctor-signature
18-
HeroListComponent(HeroService heroService) : heroes = heroService.getHeroes();
19-
//#enddocregion ctor-signature
17+
// #docregion ctor-signature
18+
HeroListComponent(HeroService heroService)
19+
// #enddocregion ctor-signature
20+
: heroes = heroService.getHeroes();
2021
}

public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
// #docplaster
12
// #docregion
23
import 'package:angular2/core.dart';
34

45
import 'hero.dart';
6+
// #enddocregion
7+
import 'hero_service_1.dart';
8+
/*
9+
// #docregion
510
import 'hero_service.dart';
11+
// #enddocregion
12+
*/
13+
// #docregion
614

715
@Component(
816
selector: 'hero-list',
@@ -13,8 +21,8 @@ import 'hero_service.dart';
1321
class HeroListComponent {
1422
final List<Hero> heroes;
1523

16-
//#docregion ctor
24+
// #docregion ctor
1725
HeroListComponent(HeroService heroService)
1826
: heroes = heroService.getHeroes();
19-
//#enddocregion ctor
27+
// #enddocregion ctor
2028
}

public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ class HeroService {
2020
.where((hero) => _isAuthorized || !hero.isSecret)
2121
.toList();
2222
}
23-
// #enddocregion internals
23+
// #enddocregion internals
2424
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// #docregion
2+
import 'package:angular2/core.dart';
3+
24
import 'hero.dart';
35
import 'mock_heroes.dart';
46

7+
@Injectable()
58
class HeroService {
69
List<Hero> getHeroes() => HEROES;
710
}

public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class HeroService {
1111

1212
//#docregion ctor
1313
HeroService(this._logger);
14-
1514
//#enddocregion ctor
1615
List<Hero> getHeroes() {
1716
_logger.log('Getting heroes ...');

public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import '../user_service.dart';
66
import 'hero_service.dart';
77

88
// #docregion factory
9-
@Injectable()
10-
heroServiceFactory(Logger logger, UserService userService) =>
9+
HeroService heroServiceFactory(Logger logger, UserService userService) =>
1110
new HeroService(logger, userService.user.isAuthorized);
1211
// #enddocregion factory
1312

0 commit comments

Comments
 (0)