Angular2 Dart - DI 〜その② 一括定義編

# DIの一括定義

今回のソースは[こちら](https://github.com/takayuki-hayashi/angular2-dart-examples/tree/master/angular-example04)

[前回](http://qiita.com/hayassh/items/e619e240177ba3915f2)のエントリーにて単純なDIの方法を書いたのですが、下記のように```SimpleAppService```を使うコンポーネント全てで```providers: const[SimpleAppService]```と記述するのは面倒です。

```dart
@Component(
    selector: 'app-sub1',
    templateUrl: 'app_sub1.html',
    providers: const[SimpleAppService])
class AppSub1 implements OnInit{
...
```

一括で定義したい場合は親コンポーネントに定義しておけば子コンポーネントにてそれぞれ定義する必要はなくなります。
親コンポーネントは下記のような感じです。

```dart:app_sub_parent.dart
@Component(
    selector: 'app-sub-parent',
    templateUrl: 'app_sub_parent.html',
    providers: const[NestedAppService, RequestService],
    directives: const [AppSub3,AppSub4]//子コンポーネントは2つ
)
class AppSubParent { //親コンポーネント
}
```

続いて```NestedAppService```を使う子コンポーネント```AppSub3```と```AppSub4```です。
```providers: const[NestedAppService, RequestService]```の定義は不要です。

```dart:app_sub3.dart
@Component(
    selector: 'app-sub3',
    templateUrl: 'app_sub3.html'
    // providersの定義は不要
)
class AppSub3 implements OnInit{

  List<String> messages;
  final NestedAppService _appService; //DIされる

  AppSub3(this._appService);

  Future<Null> initMessages() async {
    messages = await _appService.getMessages();
  }

  @override
  void ngOnInit() {
    initMessages();
  }
}
```

```dart:app_sub4.dart
@Component(
    selector: 'app-sub4',
    templateUrl: 'app_sub4.html'
    // providersの定義は不要
)
class AppSub4 implements OnInit{

  List<String> messages;
  final NestedAppService _appService;//DIされる

  AppSub4(this._appService);

  Future<Null> initMessages() async {
    messages = await _appService.getMessages();
  }

  @override
  void ngOnInit() {
    initMessages();
  }
}
```

# DI一括定義時の実装切替え

```dart
@Injectable()
class NestedAppService {
  RequestService _requestService;
  NestedAppService(this._requestService);
  Future<List<String>> getMessages() async => _requestService.getStrings();
}

@Injectable()
class RequestService {
  Future<List<String>> getStrings() async => ["data01","data02"];
}

@Injectable()
class SimpleRequestService extends RequestService{
  @override
  Future<List<String>> getStrings() async => ["simpleData01","simpleData02"];
}
```

一括定義している状況において上記のような各Serviceがある場合、コンポーネントAでは```RequestService```がDIされた```NestedAppService```を使い、コンポーネントBでは```SimpleRequestService```がDIされた```NestedApppService```を使いたい場合はどうするか。

このような場合は一括定義されていないServiceを使うコンポーネントで```providers```を定義すればそのコンポーネントだけ実装を切り替える事が出来ます。

親コンポーネント

```dart:app_sub_parent.dart
@Component(
    selector: 'app-sub-parent',
    templateUrl: 'app_sub_parent.html',
    providers: const[NestedAppService, RequestService],
    directives: const [AppSub3,AppSub4]
)
class AppSubParent {
}
```
```html:app_sub_parent.html
<h3>親コンポーネント</h3>
<app-sub3></app-sub3>
<p></p>
<app-sub4></app-sub4
```

子コンポーネント1

```dart:app_sub3.dart
@Component(
    selector: 'app-sub3',
    templateUrl: 'app_sub3.html'
)
class AppSub3 implements OnInit{

  List<String> messages;
  final NestedAppService _appService;

  AppSub3(this._appService);

  Future<Null> initMessages() async {
    messages = await _appService.getMessages();
  }

  @override
  void ngOnInit() {
    initMessages();
  }
}
```
```html
<h4>子コンポーネント1</h4>
<div *ngFor="let message of messages">
    <span style="font-weight: bold;">{{message}}</span>
</div
```


子コンポーネント2

```dart:app_sub4.dart
@Component(
    selector: 'app-sub4',
    templateUrl: 'app_sub4.html',
    providers: const[ NestedAppService, const Provider(RequestService, useClass: SimpleRequestService)]
    //RequestServiceの型はSimpleRequestServiceを使用するように定義
)
class AppSub4 implements OnInit{

  List<String> messages;
  final NestedAppService _appService;

  AppSub4(this._appService);

  Future<Null> initMessages() async {
    messages = await _appService.getMessages();
  }

  @override
  void ngOnInit() {
    initMessages();
  }
}
```
```html:app_sub4.html
<h4>子コンポーネント2</h4>
<div *ngFor="let message of messages">
    <span style="font-weight: bold;">{{message}}</span>
</div>
```

実行結果は下記になります。

![result.png](https://qiita-image-store.s3.amazonaws.com/0/134650/4b48c77f-7dda-c192-367b-946f7dcfdb80.png)

今回はここまでで。次回もまだDIについて書く予定です。