From 1ac9316171ac56f19ed5ff87147d64ef5c3aa9d1 Mon Sep 17 00:00:00 2001 From: luis Date: Sat, 6 Feb 2016 17:02:44 -0500 Subject: [PATCH] docs(dependency-injection): add Dart sample closes #817 --- .gitignore | 3 +- .../dart/lib/app_component.dart | 63 +++ .../dart/lib/app_component_1.dart | 28 ++ .../dart/lib/app_component_2.dart | 35 ++ .../dart/lib/app_config.dart | 29 ++ .../dart/lib/car/car.dart | 32 ++ .../dart/lib/car/car_component.dart | 33 ++ .../dart/lib/car/car_creations.dart | 56 +++ .../dart/lib/car/car_factory.dart | 15 + .../dart/lib/car/car_injector.dart | 36 ++ .../dart/lib/car/car_no_di.dart | 22 ++ .../dart/lib/heroes/hero.dart | 7 + .../dart/lib/heroes/hero_list_component.dart | 21 + .../lib/heroes/hero_list_component_1.dart | 16 + .../lib/heroes/hero_list_component_2.dart | 20 + .../dart/lib/heroes/hero_service.dart | 22 ++ .../dart/lib/heroes/hero_service_1.dart | 8 + .../dart/lib/heroes/hero_service_2.dart | 20 + .../lib/heroes/hero_service_provider.dart | 16 + .../dart/lib/heroes/heroes_component.dart | 15 + .../dart/lib/heroes/heroes_component_1.dart | 25 ++ .../dart/lib/heroes/mock_heroes.dart | 46 +++ .../dart/lib/injector_component.dart | 58 +++ .../dart/lib/logger_service.dart | 13 + .../dart/lib/providers_component.dart | 360 ++++++++++++++++++ .../dart/lib/user_service.dart | 27 ++ .../dependency-injection/dart/pubspec.yaml | 16 + .../dart/test/hero_list_component_test.dart | 34 ++ .../dependency-injection/dart/web/index.html | 15 + .../dependency-injection/dart/web/main.dart | 12 + .../dependency-injection/dart/web/main_1.dart | 10 + .../latest/guide/dependency-injection.jade | 9 +- 32 files changed, 1119 insertions(+), 3 deletions(-) create mode 100644 public/docs/_examples/dependency-injection/dart/lib/app_component.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/app_config.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/car/car.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/injector_component.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/logger_service.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/providers_component.dart create mode 100644 public/docs/_examples/dependency-injection/dart/lib/user_service.dart create mode 100644 public/docs/_examples/dependency-injection/dart/pubspec.yaml create mode 100644 public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart create mode 100644 public/docs/_examples/dependency-injection/dart/web/index.html create mode 100644 public/docs/_examples/dependency-injection/dart/web/main.dart create mode 100644 public/docs/_examples/dependency-injection/dart/web/main_1.dart diff --git a/.gitignore b/.gitignore index 090642e729..c69d33ad83 100644 --- a/.gitignore +++ b/.gitignore @@ -3,13 +3,14 @@ _temp bower_components jspm_packages typings -packages +**/packages build pubspec.lock .pub .packages *.map .DS_Store +**/*.iml .idea **/js/latest/api **/ts/latest/api diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_component.dart b/public/docs/_examples/dependency-injection/dart/lib/app_component.dart new file mode 100644 index 0000000000..4e01554a42 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/app_component.dart @@ -0,0 +1,63 @@ +// #docplaster + +// #docregion + +// #docregion imports +import 'package:angular2/core.dart'; +import 'car/car_component.dart'; +import 'heroes/heroes_component.dart'; +import 'app_config.dart'; +import 'logger_service.dart'; +import 'user_service.dart'; + +// #enddocregion imports +import 'injector_component.dart'; +import 'providers_component.dart'; + +@Component( + selector: 'my-app', + template: ''' +

{{title}}

+ + + +

User

+

+ {{userInfo}} + +

+ + + ''', + directives: const [CarComponent, HeroesComponent, InjectorComponent, ProvidersComponent], +// #docregion providers + providers: const [Logger, UserService, const Provider(Config, useValue: CONFIG)] +// #enddocregion providers + ) +class AppComponent { + UserService _userService; + String title; + + //#docregion ctor + AppComponent(Config config, this._userService) { + title = config.title; + } + + // #enddocregion ctor + bool get isAuthorized { + return user.isAuthorized; + } + + void nextUser() { + _userService.getNewUser(); + } + + User get user { + return _userService.user; + } + + String get userInfo { + return 'Current user, ${user.name}, is ${isAuthorized ? "" : "not"} authorized. '; + } +} +// #enddocregion diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart b/public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart new file mode 100644 index 0000000000..7c3b7b9808 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart @@ -0,0 +1,28 @@ +// Early versions + +// #docregion +import 'package:angular2/core.dart'; +import 'car/car_component.dart'; +import 'heroes/heroes_component_1.dart'; + +@Component( + selector: 'my-app', + template: ''' +

{{title}}

+ + + ''', + directives: const [CarComponent, HeroesComponent]) +class AppComponent { + var title = 'Dependency Injection'; +} +// #enddocregion + +/* +//#docregion ctor-di-fail +// FAIL! Injectable `config` is not a class! +AppComponent(HeroService heroService, Map config) { + title = config['title']; +} +//#enddocregion ctor-di-fail +*/ diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart b/public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart new file mode 100644 index 0000000000..7bf4249ee2 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart @@ -0,0 +1,35 @@ +// #docregion + +// #docregion imports +import 'package:angular2/core.dart'; +import 'car/car_component.dart'; +import 'heroes/heroes_component_1.dart'; +import 'app_config.dart'; +import 'logger_service.dart'; + +// #enddocregion imports +@Component( + selector: 'my-app', + template: ''' +

{{title}}

+ + + ''', + directives: const [ + CarComponent, + HeroesComponent + ], + providers: const [ + Logger, + // #docregion provider-config + const Provider('app.config', useValue: CONFIG) + ]) +class AppComponent { + String title; + + // #docregion ctor + AppComponent(@Inject('app.config') Config config) { + title = config.title; + } +} +// #enddocregion diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_config.dart b/public/docs/_examples/dependency-injection/dart/lib/app_config.dart new file mode 100644 index 0000000000..8fc877f188 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/app_config.dart @@ -0,0 +1,29 @@ +//#docregion + +// #docregion token +import 'package:angular2/core.dart'; + +const APP_CONFIG = const OpaqueToken('app.config'); +// #enddocregion token + +//#docregion config +abstract class Config { + final String apiEndpoint; + final String title; + + const Config({this.apiEndpoint, this.title}); +} + +class ConfigImpl implements Config { + final String apiEndpoint; + final String title; + + const ConfigImpl({this.apiEndpoint, this.title}); +} + +const CONFIG = const ConfigImpl(apiEndpoint: 'api.heroes.com', title: 'Dependency Injection'); +//#enddocregion config + +//#docregion config-hash +const CONFIG_HASH = const {'apiEndpoint': 'api.heroes.com', 'title': 'Dependency Injection'}; +//#enddocregion config-hash diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car.dart new file mode 100644 index 0000000000..4c8d1025e7 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/car/car.dart @@ -0,0 +1,32 @@ +// #docregion + +import 'package:angular2/core.dart'; + +// #docregion engine +class Engine { + int cylinders = 4; +} +// #enddocregion engine + +// #docregion tires +class Tires { + String make = 'Flintstone'; + String model = 'Square'; +} + +// #enddocregion tires +@Injectable() +class Car { + //#docregion car-ctor + Engine engine; + Tires tires; + String description = 'DI'; + + Car(this.engine, this.tires); + + // #enddocregion car-ctor + + // Method using the engine and tires + String drive() => '$description car with ${engine.cylinders} cylinders and ${tires.make} tires.'; +} +// #enddocregion car diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart new file mode 100644 index 0000000000..e8e3ccc0e0 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart @@ -0,0 +1,33 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'car.dart'; +import 'car_no_di.dart' as carNoDi; +import 'car_factory.dart'; +import 'car_creations.dart' as carCreations; +import 'car_injector.dart'; + +@Component( + selector: 'my-car', + template: ''' +

Cars

+
{{car.drive()}}
+
{{noDiCar.drive()}}
+
{{injectorCar.drive()}}
+
{{factoryCar.drive()}}
+
{{simpleCar.drive()}}
+
{{superCar.drive()}}
+
{{testCar.drive()}}
+ ''', + providers: const [Car, Engine, Tires]) +class CarComponent { + Car car; + + CarComponent(this.car) {} + Car factoryCar = (new CarFactory()).createCar(); + Car injectorCar = useInjector(); + carNoDi.Car noDiCar = new carNoDi.Car(); + Car simpleCar = carCreations.simpleCar(); + Car superCar = carCreations.superCar(); + Car testCar = carCreations.testCar(); +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart new file mode 100644 index 0000000000..33dfa05828 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart @@ -0,0 +1,56 @@ +// Examples with car and engine variations + +// #docplaster +import 'car.dart'; + +///////// example 1 //////////// +Car simpleCar() { + //#docregion car-ctor-instantiation + + // Simple car with 4 cylinders and Flintstone tires. + var car = new Car(new Engine(), new Tires()); + //#enddocregion car-ctor-instantiation + car.description = 'Simple'; + return car; +} +///////// example 2 //////////// + +//#docregion car-ctor-instantiation-with-param +class Engine2 implements Engine { + int cylinders; + + Engine2(this.cylinders); +} + +//#enddocregion car-ctor-instantiation-with-param +Car superCar() { + //#docregion car-ctor-instantiation-with-param + + // Super car with 12 cylinders and Flintstone tires. + var bigCylinders = 12; + var car = new Car(new Engine2(bigCylinders), new Tires()); + //#enddocregion car-ctor-instantiation-with-param + car.description = 'Super'; + return car; +} +/////////// example 3 ////////// + +//#docregion car-ctor-instantiation-with-mocks +class MockEngine extends Engine { + int cylinders = 8; +} + +class MockTires extends Tires { + String make = 'YokoGoodStone'; +} + +//#enddocregion car-ctor-instantiation-with-mocks +Car testCar() { + //#docregion car-ctor-instantiation-with-mocks + + // Test car with 8 cylinders and YokoGoodStone tires. + var car = new Car(new MockEngine(), new MockTires()); + //#enddocregion car-ctor-instantiation-with-mocks + car.description = 'Test'; + return car; +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart new file mode 100644 index 0000000000..76b8a4cc63 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart @@ -0,0 +1,15 @@ +// #docregion + +import 'car.dart'; + +class CarFactory { + Car createCar() { + var car = new Car(createEngine(), createTires()); + car.description = 'Factory'; + return car; + } + + Engine createEngine() => new Engine(); + + Tires createTires() => new Tires(); +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart new file mode 100644 index 0000000000..1dbadd9fab --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart @@ -0,0 +1,36 @@ +// #docplaster + +//#docregion +import 'package:angular2/core.dart'; +import 'car.dart'; +import '../logger_service.dart'; + +//#docregion injector +Car useInjector() { + Injector injector; + //#enddocregion injector + + /* +//#docregion injector-no-new + // Cannot 'new' an Injector like this! + var injector = new Injector([Car, Engine, Tires, Logger]); +//#enddocregion injector-no-new +*/ + + //#docregion injector + + //#docregion injector-create-and-call + injector = Injector.resolveAndCreate([Car, Engine, Tires, Logger]); + //#docregion injector-call + var car = injector.get(Car); + //#enddocregion injector-call + + //#enddocregion injector-create-and-call + car.description = 'Injector'; + var logger = injector.get(Logger); + logger.log('Injector car.drive() said: ' + car.drive()); + return car; +} +//#enddocregion injector + +//#enddocregion diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart new file mode 100644 index 0000000000..32972c3dc1 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart @@ -0,0 +1,22 @@ +// Car without DI + +import 'car.dart'; + +//#docregion car +class Car { + //#docregion car-ctor + Engine engine; + Tires tires; + var description = 'No DI'; + + Car() { + engine = new Engine(); + tires = new Tires(); + } + + //#enddocregion car-ctor + + // Method using the engine and tires + drive() => '$description car with ${engine.cylinders} cylinders and ${tires.make} tires.'; +} +//#enddocregion car diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart new file mode 100644 index 0000000000..ea10276b7c --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart @@ -0,0 +1,7 @@ +// #docregion + +class Hero { + num id; + String name; + bool isSecret = false; +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart new file mode 100644 index 0000000000..c4eeb14f1b --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart @@ -0,0 +1,21 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero.dart'; +import 'hero_service.dart'; + +@Component( + selector: 'hero-list', + template: ''' +
+ {{hero.id}} - {{hero.name}} + ({{hero.isSecret ? \'secret\' : \'public\'}}) +
+ ''') +class HeroListComponent { + List heroes; + +//#docregion ctor-signature + HeroListComponent(HeroService heroService) : heroes = heroService.getHeroes(); +//#enddocregion ctor-signature +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart new file mode 100644 index 0000000000..3aeef5aefb --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart @@ -0,0 +1,16 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero.dart'; +import 'mock_heroes.dart'; + +@Component( + selector: 'hero-list', + template: ''' +
+ {{hero.id}} - {{hero.name}} +
+ ''') +class HeroListComponent { + List heroes = HEROES; +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart new file mode 100644 index 0000000000..2b76419505 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart @@ -0,0 +1,20 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero.dart'; +import 'hero_service.dart'; + +@Component( + selector: 'hero-list', + template: ''' +
+ {{hero.id}} - {{hero.name}} +
+ ''') +class HeroListComponent { + List heroes; + +//#docregion ctor + HeroListComponent(HeroService heroService) : heroes = heroService.getHeroes(); +//#enddocregion ctor +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart new file mode 100644 index 0000000000..2dda48cb70 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart @@ -0,0 +1,22 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero.dart'; +import 'mock_heroes.dart'; +import '../logger_service.dart'; + +@Injectable() +class HeroService { + // #docregion internals + Logger _logger; + bool _isAuthorized; + + HeroService(this._logger, this._isAuthorized); + + List getHeroes() { + var auth = _isAuthorized ? 'authorized' : 'unauthorized'; + _logger.log('Getting heroes for ${auth} user.'); + return HEROES.where((hero) => _isAuthorized || !hero.isSecret).toList(); + } +// #enddocregion internals +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart new file mode 100644 index 0000000000..7ee6a642b4 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart @@ -0,0 +1,8 @@ +// #docregion + +import 'hero.dart'; +import 'mock_heroes.dart'; + +class HeroService { + List getHeroes() => HEROES; +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart new file mode 100644 index 0000000000..25146a76f9 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart @@ -0,0 +1,20 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero.dart'; +import 'mock_heroes.dart'; +import '../logger_service.dart'; + +@Injectable() +class HeroService { + Logger _logger; + + //#docregion ctor + HeroService(this._logger); + + //#enddocregion ctor + List getHeroes() { + _logger.log('Getting heroes ...'); + return HEROES; + } +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart new file mode 100644 index 0000000000..b783f0edc5 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart @@ -0,0 +1,16 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero_service.dart'; +import '../logger_service.dart'; +import '../user_service.dart'; + +// #docregion factory +heroServiceFactory(Logger logger, UserService userService) => + new HeroService(logger, userService.user.isAuthorized); +// #enddocregion factory + +// #docregion provider +const heroServiceProvider = + const Provider(HeroService, useFactory: heroServiceFactory, deps: const [Logger, UserService]); +// #enddocregion provider diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart new file mode 100644 index 0000000000..45e310cd30 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart @@ -0,0 +1,15 @@ +// #docregion + +import 'package:angular2/core.dart'; +import 'hero_list_component.dart'; +import 'hero_service_provider.dart'; + +@Component( + selector: 'my-heroes', + template: ''' +

Heroes

+ + ''', + providers: const [heroServiceProvider], + directives: const [HeroListComponent]) +class HeroesComponent {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart new file mode 100644 index 0000000000..80d7ad8f2e --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart @@ -0,0 +1,25 @@ +// #docplaster + +// #docregion +// #docregion v1 +import 'package:angular2/core.dart'; +import 'hero_list_component.dart'; + +// #enddocregion v1 +import 'hero_service.dart'; + +// #docregion v1 +@Component( + selector: 'my-heroes', + template: ''' +

Heroes

+ + ''', +// #enddocregion v1 +// #docregion providers + providers: const [HeroService], +// #enddocregion providers +// #docregion v1 + directives: const [HeroListComponent]) +class HeroesComponent {} +// #enddocregion v1 diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart new file mode 100644 index 0000000000..9f49bf208c --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart @@ -0,0 +1,46 @@ +// #docregion + +import 'hero.dart'; + +List HEROES = [ + new Hero() + ..id = 11 + ..isSecret = false + ..name = 'Mr. Nice', + new Hero() + ..id = 12 + ..isSecret = false + ..name = 'Narco', + new Hero() + ..id = 13 + ..isSecret = false + ..name = 'Bombasto', + new Hero() + ..id = 14 + ..isSecret = false + ..name = 'Celeritas', + new Hero() + ..id = 15 + ..isSecret = false + ..name = 'Magneta', + new Hero() + ..id = 16 + ..isSecret = false + ..name = 'RubberMan', + new Hero() + ..id = 17 + ..isSecret = false + ..name = 'Dynama', + new Hero() + ..id = 18 + ..isSecret = true + ..name = 'Dr IQ', + new Hero() + ..id = 19 + ..isSecret = true + ..name = 'Magma', + new Hero() + ..id = 20 + ..isSecret = true + ..name = 'Tornado' +]; diff --git a/public/docs/_examples/dependency-injection/dart/lib/injector_component.dart b/public/docs/_examples/dependency-injection/dart/lib/injector_component.dart new file mode 100644 index 0000000000..24e1598f13 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/injector_component.dart @@ -0,0 +1,58 @@ +// #docplaster + +//#docregion +import 'package:angular2/core.dart'; +import 'car/car.dart'; +import 'heroes/hero_service.dart'; +import 'heroes/hero_service_provider.dart'; +import 'logger_service.dart'; +import 'package:dependency_injection/heroes/hero.dart'; + +//#docregion injector +@Component( + selector: 'my-injectors', + template: ''' +

Other Injections

+
{{car.drive()}}
+
{{hero.name}}
+
{{rodent}}
+ ''', + providers: const [ + Car, + Engine, + Tires, + const Provider(HeroService, useFactory: heroServiceFactory), + Logger + ]) +class InjectorComponent { + Injector _injector; + + InjectorComponent(this._injector) { + car = _injector.get(Car); + heroService = _injector.get(HeroService); + hero = heroService.getHeroes()[0]; + } + + Car car; + + //#docregion get-hero-service + HeroService heroService; + + //#enddocregion get-hero-service + Hero hero; + + String get rodent { + var rous = _injector.getOptional(ROUS); + if (rous != null) { + throw new Exception('Aaaargh!'); + } + return "R.O.U.S.'s? I don't think they exist!"; + } +} +//#enddocregion injector + +/** + * R.O.U.S. - Rodents Of Unusual Size + * // https://www.youtube.com/watch?v=BOv5ZjAOpC8 + */ +class ROUS {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/logger_service.dart b/public/docs/_examples/dependency-injection/dart/lib/logger_service.dart new file mode 100644 index 0000000000..452daefd22 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/logger_service.dart @@ -0,0 +1,13 @@ +// #docregion + +import 'package:angular2/core.dart'; + +@Injectable() +class Logger { + List logs = []; + + void log(String message) { + logs.add(message); + print(message); + } +} diff --git a/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart b/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart new file mode 100644 index 0000000000..83d461deb2 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart @@ -0,0 +1,360 @@ +// Examples of provider arrays + +//#docplaster +import 'package:angular2/core.dart'; +import 'app_config.dart'; +import 'heroes/hero_service_provider.dart'; +import 'heroes/hero_service.dart'; +import 'logger_service.dart'; +import 'user_service.dart'; + +// #docregion import-optional +import 'package:angular2/core.dart' show Optional; +// #enddocregion import-optional + +const template = '{{log}}'; + +////////////////////////////////////////// +@Component(selector: 'provider-1', template: '{{log}}', providers: +//#docregion providers-1 +const [Logger] +//#enddocregion providers-1 +) +class ProviderComponent1 { + String log; + + ProviderComponent1(Logger logger) { + logger.log('Hello from logger provided with Logger class'); + log = logger.logs[0]; + } +} + +////////////////////////////////////////// +@Component(selector: 'provider-2', template: '{{log}}', providers: +//#docregion providers-2 +const [const Provider(Logger, useClass: Logger)] +//#enddocregion providers-2 +) +class ProviderComponent2 { + String log; + + ProviderComponent2(Logger logger) { + logger.log('Hello from logger provided with Provider class and useClass'); + log = logger.logs[0]; + } +} + +////////////////////////////////////////// +@Component( + selector: 'provider-3', + template: '{{log}}', + providers: const [const Provider(Logger, useClass: Logger)] +/* +//#docregion providers-3 + const [provide(Logger, useClass: Logger)] +//#enddocregion providers-3 +*/ +) +class ProviderComponent3 { + String log; + + ProviderComponent3(Logger logger) { + logger.log('Hello from logger provided with useClass'); + log = logger.logs[0]; + } +} + +////////////////////////////////////////// +class BetterLogger extends Logger {} + +@Component(selector: 'provider-4', template: '{{log}}', providers: +//#docregion providers-4 +const [const Provider(Logger, useClass: BetterLogger)] +//#enddocregion providers-4 +) +class ProviderComponent4 { + String log; + + ProviderComponent4(Logger logger) { + logger.log('Hello from logger provided with useClass:BetterLogger'); + log = logger.logs[0]; + } +} +////////////////////////////////////////// + +// #docregion EvenBetterLogger +@Injectable() +class EvenBetterLogger implements Logger { + UserService _userService; + + List logs = []; + + EvenBetterLogger(this._userService); + + log(String message) { + message = 'Message to ${ _userService.user.name}: ${ message}.'; + print(message); + logs.add(message); + } +} + +// #enddocregion EvenBetterLogger +@Component(selector: 'provider-5', template: '{{log}}', providers: +//#docregion providers-5 +const [UserService, const Provider(Logger, useClass: EvenBetterLogger)] +//#enddocregion providers-5 +) +class ProviderComponent5 { + String log; + + ProviderComponent5(Logger logger) { + logger.log('Hello from EvenBetterlogger'); + log = logger.logs[0]; + } +} + +////////////////////////////////////////// +class NewLogger extends Logger implements OldLogger {} + +class OldLogger { + List logs = []; + + log(String message) { + throw new Exception('Should not call the old logger!'); + } +} + +@Component(selector: 'provider-6a', template: '{{log}}', providers: +//#docregion providers-6a +const [ + NewLogger, +// Not aliased! Creates two instances of `NewLogger` + const Provider(OldLogger, useClass: NewLogger) +] +//#enddocregion providers-6a +) +class ProviderComponent6a { + String log; + + ProviderComponent6a(NewLogger newLogger, OldLogger oldLogger) { + if (identical(newLogger, oldLogger)) { + throw new Exception('expected the two loggers to be different instances'); + } + oldLogger.log('Hello OldLogger (but we want NewLogger)'); + // The newLogger wasn't called so no logs[] + + // display the logs of the oldLogger. + log = newLogger.logs == null || newLogger.logs.isEmpty ? oldLogger.logs[0] : newLogger.logs[0]; + } +} + +@Component(selector: 'provider-6b', template: '{{log}}', providers: +//#docregion providers-6b +const [ + NewLogger, +// Alias OldLogger w/ reference to NewLogger + const Provider(OldLogger, useExisting: NewLogger) +//#enddocregion providers-6b +]) +class ProviderComponent6b { + String log; + + ProviderComponent6b(NewLogger newLogger, OldLogger oldLogger) { + if (!identical(newLogger, oldLogger)) { + throw new Exception('expected the two loggers to be the same instance'); + } + oldLogger.log('Hello from NewLogger (via aliased OldLogger)'); + log = newLogger.logs[0]; + } +} +////////////////////////////////////////// + +// #docregion silent-logger + +// An object in the shape of the logger service +class SilentLogger /*implements Logger*/ { + const SilentLogger({this.logs}); + + final List logs; + + log(String message) {} +} + +const silentLogger = const SilentLogger( + logs: const ['Silent logger says "Shhhhh!". Provided via "useValue"']); +// #enddocregion silent-logger + +@Component(selector: 'provider-7', template: '{{log}}', providers: +//#docregion providers-7 +const [const Provider(SilentLogger, useValue: silentLogger)] +//#enddocregion providers-7 +/* +//#docregion providers-7-unchecked +const [const Provider(Logger, useValue: silentLogger)] +//#enddocregion providers-7-unchecked + */ +) +class ProviderComponent7 { + String log; + + ProviderComponent7(SilentLogger logger) { + logger.log('Hello from logger provided with useValue'); + log = logger.logs[0]; + } +} + +///////////////// +@Component(selector: 'provider-8', template: '{{log}}', providers: const [ + const Provider(HeroService, useFactory: heroServiceFactory), + Logger, + UserService +]) +class ProviderComponent8 { + // #docregion provider-8-ctor + ProviderComponent8(HeroService heroService); + + // #enddocregion provider-8-ctor + + // must be true else this component would have blown up at runtime + var log = 'Hero service injected successfully'; +} + +///////////////// +@Component(selector: 'provider-9a', template: '{{log}}', providers: +/* + // #docregion providers-9a-interface + // WOKRKS! Can use abstract class as provider token + [provide(Config, {useValue: CONFIG})] + // #enddocregion providers-9a-interface + */ + +// #docregion providers-9a +// Use string as provider token +const [const Provider('app.config', useValue: CONFIG_HASH)] +//#enddocregion providers-9a +) +class ProviderComponent9a implements OnInit { + Config _config; + + String log; + + /* + // #docregion provider-9a-ctor-interface + // WORKS! Can inject using the abstract class as the parameter type + Config _config; + + ProviderComponent9a(this._config); + // #enddocregion provider-9a-ctor-interface + */ + + // #docregion provider-9a-ctor + + // @Inject(token) to inject the dependency + ProviderComponent9a(@Inject('app.config') Map config) { + _config = new ConfigImpl(apiEndpoint: config['apiEndpoint'], title: config['title']); + } + + // #enddocregion provider-9a-ctor + ngOnInit() { + log = '\'app.config\' Application title is ' + _config.title; + } +} + +@Component(selector: 'provider-9b', template: '{{log}}', providers: +// #docregion providers-9b +const [const Provider(APP_CONFIG, useValue: CONFIG_HASH)]) // #enddocregion providers-9b +class ProviderComponent9b + implements OnInit { + Config _config; + + String log; + + // #docregion provider-9b-ctor + ProviderComponent9b(@Inject(APP_CONFIG) Map config) { + _config = new ConfigImpl(apiEndpoint: config['apiEndpoint'], title: config['title']); + } + + // #enddocregion provider-9b-ctor + ngOnInit() { + log = 'APP_CONFIG Application title is ' + _config.title; + } +} +////////////////////////////////////////// + +// Normal required logger +@Component(selector: 'provider-10a', template: '{{log}}', +//#docregion providers-logger + providers: const [Logger] +//#enddocregion providers-logger +) +class ProviderComponent10a { + String log; + + ProviderComponent10a(Logger logger) { + logger.log('Hello from the required logger.'); + log = logger.logs[0]; + } +} + +// Optional logger +@Component(selector: 'provider-10b', template: '{{log}}') +class ProviderComponent10b implements OnInit { + Logger _logger; + + // #docregion provider-10-ctor + String log; + + ProviderComponent10b(@Optional() this._logger); + + // #enddocregion provider-10-ctor + ngOnInit() { + // #docregion provider-10-logger + + // No logger? Make one! + if (_logger == null) { + _logger = new Logger(); + // #enddocregion provider-10-logger + _logger.log('Optional logger was not available.'); + } else { + _logger.log('Hello from the injected logger.'); + log = _logger.logs[0]; + } + log = _logger.logs[0]; + } +} + +///////////////// +@Component( + selector: 'my-providers', + template: ''' +

Provider variations

+
+
+
+
+
+
+
+
+
+
+
+
+
+ ''', + directives: const [ + ProviderComponent1, + ProviderComponent2, + ProviderComponent3, + ProviderComponent4, + ProviderComponent5, + ProviderComponent6a, + ProviderComponent6b, + ProviderComponent7, + ProviderComponent8, + ProviderComponent9a, + ProviderComponent9b, + ProviderComponent10a, + ProviderComponent10b + ]) +class ProvidersComponent {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/user_service.dart b/public/docs/_examples/dependency-injection/dart/lib/user_service.dart new file mode 100644 index 0000000000..682a42b967 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/lib/user_service.dart @@ -0,0 +1,27 @@ +// #docregion + +import 'package:angular2/core.dart'; + +@Injectable() +class UserService { + UserService() { + user = _bob; + } + + // Todo: get the user; don't 'new' it. + User _alice = new User('Alice', true); + User _bob = new User('Bob', false); + + // initial user is Bob + User user; + + // swaps users + User getNewUser() => user = user == _bob ? _alice : _bob; +} + +class User { + String name; + bool isAuthorized; + + User(this.name, [this.isAuthorized = false]); +} diff --git a/public/docs/_examples/dependency-injection/dart/pubspec.yaml b/public/docs/_examples/dependency-injection/dart/pubspec.yaml new file mode 100644 index 0000000000..1eb496fe73 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/pubspec.yaml @@ -0,0 +1,16 @@ +name: dependency_injection +description: Dependency injection sample +version: 0.0.1 +description: Dependency injection sample +dependencies: + angular2: ^2.0.0-beta.6 + browser: ^0.10.0 +transformers: +- angular2: + platform_directives: + - 'package:angular2/common.dart#COMMON_DIRECTIVES' + platform_pipes: + - 'package:angular2/common.dart#COMMON_PIPES' + entry_points: web/main.dart +dev_dependencies: + test: any diff --git a/public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart b/public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart new file mode 100644 index 0000000000..0dd76b4f15 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart @@ -0,0 +1,34 @@ +// A simple test +// More details will be in the testing chapter. +import 'package:angular2/angular2.dart'; +import 'package:dependency_injection/heroes/hero.dart'; +import 'package:dependency_injection/heroes/hero_list_component.dart'; +import 'package:dependency_injection/heroes/hero_service.dart'; +import 'package:test/test.dart'; + +/////////////////////////////////////// +////#docregion spec +List expectedHeroes = [ + new Hero() + ..id = 1 + ..name = 'hero1', + new Hero() + ..id = 2 + ..name = 'hero2' + ..isSecret = true +]; + +class HeroServiceMock implements HeroService { + @override + List getHeroes() => expectedHeroes; +} + +var mockService = new HeroServiceMock(); + +void main() { + test('should have heroes when HeroListComponent created', () { + var hlc = new HeroListComponent(mockService); + expect(hlc.heroes.length, expectedHeroes.length); + }); +} +//#enddocregion spec \ No newline at end of file diff --git a/public/docs/_examples/dependency-injection/dart/web/index.html b/public/docs/_examples/dependency-injection/dart/web/index.html new file mode 100644 index 0000000000..66f07c0838 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/web/index.html @@ -0,0 +1,15 @@ + + + + + Dependency Injection + + + + + +Loading my-app ... +Loading my-providers ... + + + diff --git a/public/docs/_examples/dependency-injection/dart/web/main.dart b/public/docs/_examples/dependency-injection/dart/web/main.dart new file mode 100644 index 0000000000..8e908cc892 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/web/main.dart @@ -0,0 +1,12 @@ +//#docregion + +import 'package:angular2/platform/browser.dart'; +import 'package:dependency_injection/app_component.dart'; +import 'package:dependency_injection/providers_component.dart'; + +main() { + //#docregion bootstrap + bootstrap(AppComponent); + //#enddocregion bootstrap + bootstrap(ProvidersComponent); +} \ No newline at end of file diff --git a/public/docs/_examples/dependency-injection/dart/web/main_1.dart b/public/docs/_examples/dependency-injection/dart/web/main_1.dart new file mode 100644 index 0000000000..ff9166ccf1 --- /dev/null +++ b/public/docs/_examples/dependency-injection/dart/web/main_1.dart @@ -0,0 +1,10 @@ +import 'package:angular2/platform/browser.dart'; +import 'package:dependency_injection/app_component.dart'; +import 'package:dependency_injection/heroes/hero_service.dart'; +//#docregion bootstrap + +main() { +// Injecting services in bootstrap works but is discouraged + bootstrap(AppComponent, [HeroService]); +//#enddocregion bootstrap +} \ No newline at end of file diff --git a/public/docs/dart/latest/guide/dependency-injection.jade b/public/docs/dart/latest/guide/dependency-injection.jade index 75279356e6..34cc0ee01d 100644 --- a/public/docs/dart/latest/guide/dependency-injection.jade +++ b/public/docs/dart/latest/guide/dependency-injection.jade @@ -2,5 +2,10 @@ include ../../../../_includes/_util-fns :marked We're working on the Dart version of this chapter. - In the meantime, please read the - [TypeScript version of this chapter](/docs/ts/latest/guide/dependency-injection.html). + In the meantime, please see these resources: + + * [Dependency Injection](/docs/ts/latest/guide/dependency-injection.html): + The TypeScript version of this chapter + + * [Dart source code](https://github.com/angular/angular.io/tree/master/public/docs/_examples/dependency-injection/dart): + A preliminary version of the example code that will appear in this chapter