DIの一括定義
今回のソースはこちら
前回のエントリーにて単純なDIの方法を書いたのですが、下記のようにSimpleAppService
を使うコンポーネント全てでproviders: const[SimpleAppService]
と記述するのは面倒です。
@Component(
selector: 'app-sub1',
templateUrl: 'app_sub1.html',
providers: const[SimpleAppService])
class AppSub1 implements OnInit{
...
一括で定義したい場合は親コンポーネントに定義しておけば子コンポーネントにてそれぞれ定義する必要はなくなります。
親コンポーネントは下記のような感じです。
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]
の定義は不要です。
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();
}
}
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一括定義時の実装切替え
@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
を定義すればそのコンポーネントだけ実装を切り替える事が出来ます。
親コンポーネント
app_sub_parent.dart
@Component(
selector: 'app-sub-parent',
templateUrl: 'app_sub_parent.html',
providers: const[NestedAppService, RequestService],
directives: const [AppSub3,AppSub4]
)
class AppSubParent {
}
app_sub_parent.html
<h3>親コンポーネント</h3>
<app-sub3></app-sub3>
<p></p>
<app-sub4></app-sub4
子コンポーネント1
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();
}
}
<h4>子コンポーネント1</h4>
<div *ngFor="let message of messages">
<span style="font-weight: bold;">{{message}}</span>
</div
子コンポーネント2
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();
}
}
app_sub4.html
<h4>子コンポーネント2</h4>
<div *ngFor="let message of messages">
<span style="font-weight: bold;">{{message}}</span>
</div>
実行結果は下記になります。
今回はここまでで。次回もまだDIについて書く予定です。