2016-06-15 5 views
2

私が直面している問題は、実際には親子階層に属さない2つの独立したスコープを持つことです。私の場合、2種類のスコープが必要です:ダガー2 - 複数の独立スコープのコンポーネントから単一のオブジェクトに注入

1) "Feature"ベースのスコープ。例えば、ユーザが機能を入力すると、スコープ付きコンポーネントが作成される。ユーザーがその機能を離れると、そのスコープは破棄されます。

2)「アクティビティ」ベースのスコープ(これはAndroidアプリ用です。Androidを使用しない場合はごめんなさい)。アクティビティが作成されると、スコープ付きコンポーネントが作成されます。アクティビティが破壊されると、そのスコープは破壊されます。

サブコンポーネントやコンポーネントの依存関係は、私が後にしているもののために機能します。これは、アクティビティが破棄される前に機能が終了する可能性があるためです。同様に、アクティビティは機能が終了する前に終了する可能性があります。

メンバーインジェクションメソッドの代わりにプロビジョニングメソッドを使用し、2つの別々のコンポーネントを保持できることはわかっていますが、ただちにinjectのすべての依存関係を1つのオブジェクトに入れることが簡単です。誰にもこれに関する考えはありますか?

+2

機能には一般的に明確なライフサイクルがないため、機能にスコープを一致させるのは非常に困難です。例えば。アカウント管理機能にはログインを管理するためのアクティビティレベルのオブジェクトが含まれていますが、ログインしているユーザーの概念は一般的なアンドロイドオブジェクトライフサイクルの任意の数に及ぶ可能性があります。 feature _modules_を作成し、その機能が必要なコンポーネントにインストールすることを強くお勧めします。独自に行う必要がある状態管理がある場合は、手動で行い、スコープのないプロバイダを注入するだけです。 – gk5885

+0

返信いただきありがとうございます。特に、著者の見解を聞くのは良いです。 Btwは、私が後になっている状態管理だけでなく、リスナーが付いているオブジェクトのために、同じインスタンスが「機能」の存続期間中に注入されるようにしたいと考えています。あなたの例では、ユーザーがログアウトを選択したときにスコープが終了する可能性があり、多くのアンドロイドオブジェクトにまたがっているにもかかわらず、スコープはうまく定義されています。典型的なアクティビティやフラグメントベースのナビゲーションでは、ユーザーが現在どのスコープ内にあるのかを知ることは難しいでしょう。しかし、[Flow](https://github.com/square/flow)を使うと、とても簡単です。 –

答えて

0

これは私が考えることができる最高のソリューションです。アクティビティ関連のオブジェクトを私のアプリケーション内の他の州に連結し、このようなものを実装するのと同じように感じました。

アプリケーションスコープ、アクティビティスコープ、およびフィーチャースコープの3つのスコープ(プロファイル情報などを持つユーザーログイン状態など)があるとします。アクティビティーとフィーチャーのスコープはアプリケーションスコープの子ですが、フィーチャーとアクティビティは無関係の兄弟です。

Featuredスコープオブジェクトをアクティビティに直接挿入しないでください。代わりに、機能スコープ側にゲッターを含むブリッジを挿入します。

例:

public interface UserManager { 
    @Nullable 
    User getLoggedInUser(); 

    @Nullable 
    ShoppingCart getShoppingCart(); 
} 

ユーザーがまたは他のオブジェクトがそれらにアクセスしようとしたときに記録してもしなくてもよいため、これらのメソッドがNULL可能です。 nullの場合、ユーザーはログインしていません。この機能は有効になっていません。

この実装は、アクティビティスコープから何も参照しないため、フィーチャスコープ側からの依存性注入を自由に実行します。

public class UserManagerImpl implements UserManager { 
    @Inject 
    ShoppingCart cart; 

    @Inject 
    User user; 

    public UserManagerImpl(MyApplication application){ 
     UserScopeComponent component = application.getUserComponent(); 
     if(component != null) { 
      //only attempt injection if the component exists (user is logged in) 
      component.inject(this); 
     } 
    } 

    //put simple getters here. They will return null objects if the component didnt inject anything. 
} 

ApplicationModuleは、このオブジェクトを提供します。これはアプリケーションスコープでもシングルトンでもありません。ログイン状態が変更された場合に注入されるたびに再度初期化します。あなたは、あなたのアプリケーション内のどこからのUserManagerを注入そのゲッターを呼び出し、出力がnullでないかどうかを確認し、離れてあなたが行くことができる上から

@Provides 
//No Scope 
UserManager provideUserManager(){ 
    return new UserManagerImpl(context); 
} 

。あなたのフィーチャーの状態はもはやアクティビティ状態に結合されず、自由になることができます。

関連する問題