3

グラフ内のオブジェクトのライフサイクルの作成と管理を担当する手作りのコンテナー/インジェクターを使用する場合、次のパターンを使用します (ObjC での DIY DI に関する記事を読みました)。

別のビュー コントローラー (詳細ビュー コントローラーと呼びましょう) を表示したいルート ビュー コントローラーがあり、データを渡しているとします。私が通常行うことは、データを引数として受け取り、表示する新しいビュー コントローラーを返すプロバイダー ブロックを挿入することです。ここにいくつかのコードがあります...

@implementation RootViewController
{
    UIViewController (^detailViewControllerProvider)(SomeData *someData);
}

- (id) initWithDetailViewControllerProvider:(UIViewController (^)(SomeData *someData))detailViewControllerProvider
{
   //...
   _detailViewControllerProvider = detailViewControllerProvider;
   //...
}

// ...

- (void) presentDetailViewControllerWithData:(SomeData *)someData
{
    UIViewController *detailViewController = _detailViewControllerProvider(someData);
    [self presentViewController:detailViewController animated:YES completion:nil];
}

@end

ファクトリ クラスを使用することもできますが、この方法では、コンテナー クラスにプロバイダー ブロックを作成するだけで新しいクラスを作成することを回避できます。

問題は、Typhoon を DI コンテナーとして使用したい場合です。どうすれば同じパターンを使用できますか? 私の詳細ビューコントローラーでは、他のものを注入しています。コンストラクター注入を引き続き使用したいので、私ではなくコンポーネントファクトリによって作成されることを好みます。詳細 VC を作成するためのファクトリ クラスを作成し、後で詳細 VC に注入する依存関係を (ファクトリ) に注入することもできますが、ブロック ベースのソリューションと比較すると、作業が多すぎるようです。

ルート ビュー コントローラーからコンポーネント ファクトリにアクセスしたくありません。また、someData のセッター インジェクションも使用しません。

これに対する解決策はありますか?

4

3 に答える 3

2

TyphoonComponentFactory を注入するには:

  • クラスでライフサイクル メソッドをオーバーライドできます- (void)typhoonSetFactory:(id)theFactory
  • アセンブリ インターフェイスでは、プロパティまたは引数を挿入できますself

どちらの場合でも、どのTyphoonAssemblyインターフェイスもファクトリの前でポーズをとることができます。たとえば、 というアセンブリがある場合NetworkAssembly、タイプのプロパティを定義し、NetworkAssemblyそれとしてファクトリを注入できます。この機能のドキュメントはこちらです。

このアプローチを使用して、次のような独自の工場を展開できます。

  • コンテナーから静的依存関係をプルします。
  • ファクトリ インターフェイスからランタイム引数とともに静的依存関係を注入することにより、要件コンポーネントをインスタンス化します。

ランタイム引数付きの Typhoon ファクトリ:

TyphoonAssemblyインターフェースは上記のパターンを実装できるようになりました。

例:

- (UserDetailsController *)userDetailsControllerForUser:(User *)user
{
    return [TyphoonDefinition withClass:[UserDetailsViewController class]   
        configuration:^(TyphoonDefinition *definition) {

        [definition useInitializer:@selector(initWithPhotoService:user) 
            parameters:^(TyphoonMethod *initializer) {

            [initializer injectParameterWith:[self photoService];
           [initializer injectParameterWith:user];
        }];
    }];
}

次に、コンポーネントを解決します。

User* aUser = self.selectedUser;
UserDetailsViewController* detailsController = 
    [assembly userDetailsControllerForUser:aUser];

この機能のドキュメントはこちらです。

于 2013-12-06T01:07:34.460 に答える
2

私は工場と一緒に行きます。
少しオーバーヘッドがかかるように思えますが、TDD を実行すると、ファクトリを簡単にモックしてコントローラーを個別にテストできるため、作業が大幅に簡素化されます。
台風にもよく効きます。

于 2013-12-05T17:58:57.107 に答える