2

アプリケーションが起動すると、他の依存関係を構成するために必要な情報 (URL など) を含むリモート構成ファイルをフェッチします。

リモート構成をフェッチした後、Config他の に提供する必要があるオブジェクトがありますTyphoonDefinition

現在、plist ストーリーボード統合も使用しています。

私は元々、Config オブジェクトをロードする ViewController にアセンブリを挿入するという道をたどっていました。リモート構成を受け取って Config オブジェクトを作成すると、アセンブリのプロパティとして何らかの方法で設定していました。定義でプロパティを使用できることを期待してこれを行いましたが、これは機能せず、次のようになりました。

2014-10-22 21:18:06.203 four[39840:516543] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'No component matching id 'setConfig:'.'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010a3e63f5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010a07fbb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010a3e632d +[NSException raise:format:] + 205
    3   four                                0x00000001070a011d -[TyphoonComponentFactory componentForKey:args:] + 148
    4   CoreFoundation                      0x000000010a2de22c __invoking___ + 140
    5   CoreFoundation                      0x000000010a2de082 -[NSInvocation invoke] + 290
    6   CoreFoundation                      0x000000010a36d456 -[NSInvocation invokeWithTarget:] + 54
    7   four                                0x000000010709d358 -[TyphoonBlockComponentFactory forwardInvocation:] + 276

実行時にオブジェクトをアセンブリに挿入する方法はありますか?

私がやろうとしていることを行うためのよりクリーンな方法はありますか?

私が必要としているように聞こえるランタイム引数について読んでいましたが、ドキュメントを本当に理解していません。

たとえば、私はこれを定義として持っています。ランタイム Config オブジェクトをパラメーターとしてコンストラクターに渡す必要があります。

- (id<ApiService>)apiService
{
    return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {}];
}
4

2 に答える 2

2

ランタイム引数の使用

たとえば、私はこれを定義として持っています。ランタイム Config オブジェクトをパラメーターとしてコンストラクターに渡す必要があります。

- (id<ApiService>)apiService {
return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {}]; }

次のようなことを試してください:

- (id<ApiService>)apiServiceWithConfig:(Config *)config {
    return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {

        // inject into property: 
        [definition injectProperty:@selector(config) with:config];

        // inject into constructor:
        [definition useInitializer:@selector(initWithConfig:) parameters:^(TyphoonMethod *initializer) {
            [initializer injectParameterWith:config];
        }];

    }]; 
}

工場定義の使用

次の 2 つの定義を見てください。

- (Config *)currentConfig {
    return [TyphoonDefinition withFactory:[self configManager] selector:@selector(currentConfig)];
}

 - (ConfigManager *)configManager {
     return [TyphoonDefinition withClass:[ConfigManager class] configuration:^(TyphoonDefinition *definition){
         definition.scope = TyphoonScopeSingleton;
     }];
 }

リモート構成をダウンロードして「currentConfig」プロパティとして保存する ConfigManager があると想像してください。「configManager」定義はそのオブジェクトを記述します。

次に、「currentConfig」の定義を確認してください。この定義は、ConfigManager インスタンスで「currentConfig」メソッドを呼び出した結果を返すだけです。

次に、構成を次のように挿入できます。

- (id<ApiService>)apiService {
    return [TyphoonDefinition withClass:[ApiService class] configuration:^(TyphoonDefinition* definition) {
        [definition injectProperty:@selector(config) with:[self currentConfig]];
    }]; 
}

ただし、「apiService」の作成中に currentConfig が読み込まれた (nil ではない) ことを確認してください。(代わりに ConfigManager を注入する方がよいかもしれません - currentConfig nil の場合、後で埋められます)

于 2014-10-23T04:02:46.183 に答える
1

いくつかのポイント:

  • ランタイム引数は非常に優れた機能で、Typhoon のパワーをフルに活用するのに本当に役立ちます。それらについて学ぶことを強くお勧めします (必要に応じて、ここで質問してください)。ただし、それらはあなたがやろうとしていることには適していません。
  • 以下を使用して、実行時にコンテナーに新しい定義を登録することができます。

.

- (void)registerDefinition:(TyphoonDefinition *)definition;

. . あなたの場合もおそらくこれをしたくないでしょう。


あなた興味を持っているのは:

TyphoonComponentFactoryPostProcessor および TyphoonComponentPostProcessor:

Typhoon には 2 種類のインターフェイスをアタッチできます。1 つはTyphoonComponentFactoryPostProcessorで、もう1 つはTyphoonComponentPostProcessorです。これらは内部で使用されますが、独自に作成して、あらゆる種類のクールなことを行うこともできます。

  • TyphoonComponentFactoryPostProcessor:コンポーネントがビルドされる前に、コンポーネントの定義(レシピ) を変更します。

  • TyphoonComponentPostProcessor: ビルド後にインスタンスを変更します。


TyphoonConfig:

説明したタスクに使用できる既存の TyphoonComponentFactoryPostProcessor があります。これはTyphoonConfigPostProcessorと呼ばれ、こちらのユーザー ガイドで説明されています

すべてのポスト プロセッサは、次のように、ビルド時 (アセンブリ内) または実行時に接続できます。

TyphoonConfigPostProcessor* configurer = [[TyphoonConfigPostProcessor alloc] init];
[configurer useResourceWithName:@"Configuration.plist"]];
[factory attachPostProcessor:configurer];


TyphoonComponentFactoryPostProcessor は定義を変更するため、既にビルドされているシングルトン スコープのコンポーネントがある場合、それらは影響を受けないことに注意してください。遅延シングルトンを作成するか、 を呼び出す必要があります[factory unload]


起動後に TyphoonComponentFactory への参照を取得するにはどうすればよいですか?

アプリ内で構成ステップを実行しているものは、「台風対応」にする必要があります。これを行うには、次を使用します。

- (ConfigController *)configController
{
    return [ConfigController withClass:[INFGiftDeliveryAddressController class] 
        configuration:^(TyphoonDefinition *definition)
    {        
        [definition injectProperty:@selector(factory) with:self];
    }];

. . TyphoonComponentFactoryアセンブリを挿入するときに、タイプのプロパティまたはアセンブリ サブクラスのいずれかを宣言できます。どちらの方法でも機能します。この機能のドキュメントはこちらです。

モバイルおよびデスクトップ アプリケーションでは、多くの場合、コンポーネントを 'Typhoon 対応' にする必要があります。これにより、あるオブジェクト グラフ (ビュー コントローラーなど) から別のオブジェクト グラフに進むことができます (ランタイム引数機能が役立つ場合があります)。 . 独自のドメイン固有のアセンブリ インターフェイスにコーディングしているため、Typhoon は「非侵襲的」であることに注意してください。ほとんどの場合、アプリは Typhoon API を直接参照しません。

ここではかなり多くのことを取り上げました。さらに質問がある場合や説明が必要な場合は、遠慮なく質問してください。

于 2014-10-23T02:52:49.417 に答える