依存関係の定義方法
Typhoon Frameworkでは、依存関係をTyphoonAssemblyのサブクラスとして定義していきます。protocolに対して具象クラスを注入する場合には、その具象クラスを登録します。
TyphoonAssemblyは複数のファイルに分割したり、継承したりするこもとできます。
初期化 vs プロパティ
TyphoonAssemblyによる依存関係の定義では、初期化時の注入と、プロパティによる注入のいずれかを選んで定義することになります。
以下のサンプルコードは、Typhoon Frameworkのドキュメントから引用しています。
引用元
https://github.com/typhoon-framework/Typhoon/wiki/Assembling-Components-with-Blocks
初期化時の注入
オブジェクト初期化時に依存関係を注入します。これが一番ベーシックな使い方です。
初期化に使うメソッドのセレクタと、与える引数を順に指定して行きます。injectWithDefinitionを使うことで、Typhoonによって管理されている他のオブジェクトを注入することもできます。
- (id)basicKnight
{
return [TyphoonDefinition withClass:[Knight class] initialization:^(TyphoonInitializer* initializer)
{
initializer.selector = @selector(initWithQuest:);
//For more control, you can use injectParameterAtIndex or withName, but probably just. . .
[initializer injectWithDefinition:[self defaultQuest]];
//. . . which means the order will follow that of the parameters in the selector.
}];
}
プロパティによる注入
オブジェクトの初期化後、setterにより注入を行います。
注入するプロパティを一つずつ指定して行きます。プロパティの型に対して、注入すべき依存関係が一意に決まる場合にはプロパティ名だけを指定します。もちろん、明示的に注入するオブジェクトの定義を与えることもできます。
- (id)cavalryMan
{
return [TyphoonDefinition withClass:[CavalryMan class] properties:^(TyphoonDefinition* definition)
{
//wire-by type
[definition injectProperty:@selector(quest)];
//explicit wiring - useful when there's more than one component representing a given type
[definition injectProperty:@selector(quest) withDefinition:[self defaultQuest]];
}];
}
どちらを使うべきか?
僕は初期化が完了したオブジェクトはその時点で有効であるべきと考えているので、可能な限り初期化時に注入を行っています。
ただ、この場合循環参照の問題が起こりやすいので、必要に応じてProviderを注入します。Providerについてはまた別のエントリを書こうと思います。