2017-02-24 5 views
0

私はそれを理解している多くの例を通して、私のアプリケーションにdagger2依存関係を設定しました。私が見つけていないのは、一度注入されるとすべての依存関係を使う正しい方法です。Dagger2依存グラフ全体を使用する

モジュール内の各シングルトンは、その前のシングルトンの出力に依存します。必要な入力を得るために各シングルトンを順番に呼び出すことなく、依存グラフ全体をどのように使用しますか?

AppComponent

@Singleton 
@Component(modules = { 
     DownloaderModule.class 
}) 
public interface AppComponent { 
    void inject(MyGameActivity activity); 
} 

DownloaderModule

@Module 
public class DownloaderModule { 

    public static final String NETWORK_CACHE = "game_cache"; 

    private static final int GLOBAL_TIMEOUT = 30; // seconds 

    public DownloaderModule(@NonNull String endpoint) { 
     this(HttpUrl.parse(endpoint)); 
    } 

    @Provides @NonNull @Singleton 
    public HttpUrl getEndpoint() { 
     return this.endpoint; 
    } 

    @Provides @NonNull @Singleton @Named(NETWORK_CACHE) 
    public File getCacheDirectory(@NonNull Context context) { 
     return context.getDir(NETWORK_CACHE, Context.MODE_PRIVATE); 
    } 

    @Provides @NonNull @Singleton 
    public Cache getNetworkCache(@NonNull @Named(NETWORK_CACHE) File cacheDir) { 
     int cacheSize = 20 * 1024 * 1024; // 20 MiB 
     return new Cache(cacheDir, cacheSize); 
    } 

    @Provides @NonNull @Singleton 
    public OkHttpClient getHttpClient(@NonNull Cache cache) { 
     return new OkHttpClient.Builder() 
       .cache(cache) 
       .connectTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS) 
       .readTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS) 
       .writeTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS) 
       .build(); 
    } 

MyGameApp

public class MyGameApp extends Application { 

    private AppComponent component; 

    private static Context context; 

    public static MyGameApp get(@NonNull Context context) { 
     return (MyGameApp) context.getApplicationContext(); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     component = buildComponent(); 
     MyGameApp.context = getApplicationContext(); 

     } 

    public AppComponent component() { 
     return component; 
    } 

    protected AppComponent buildComponent() { 
     return DaggerAppComponent.builder() 
       .downloaderModule(new DownloaderModule("https://bogus.com/")) 
       .build(); 
    } 

} 
+1

"それ以前にシングルトンの出力に依存する"ということをどうやって意味していますか?あなたのモジュールは、各ピースを対応する '@ Provides'メソッドの入力パラメータとして取ることによって、必要な各ピースを注入するように適切に構成されているようです。あなたはMyGameActivityの中で作成した 'OkHttpClient'やその他の依存関係を注入することができます。 –

+0

私は単純に頭がおかしくなっていません。私はもう少し読んで、コンセプトは沈んでいます。不満は、セットアップ方法を示す記事がたくさんありますが、実際の使用例は見つけるのが難しいです。私はまともな例で今働いています。ありがとう。 –

答えて

1

私はこれにいくつかの光を当てることを試みるが、そこにあるでしょう:次を考える

あなたがこれを読むことができるいくつかの方法。私はボトムアップアプローチを好む - 基本的にあなたのオブジェクトが必要とするものを開始し、私の方法を働かせます。この場合は、MyGameActivityから開始します。残念ながら、このコードを貼り付けていないので、少し創造的でなければなりませんが、エクササイズの目的では問題ありません。

あなたのアプリではおそらくAppComponentが表示され、MyGameActivityにはinjectがコールされています。ですから、私はこの活動に注入可能なフィールドがいくつかあると思います。私はあなたがそこに直接OkHttpClientを使用しているかどうかはわかりませんが、あなたが言うとしましょう。何かのように:

public class MyGameActivity extends SomeActivity { 
    @Inject 
    OkHttpClient okHttpClient; 
    // ... 
} 

私はこれについて考える方法は次のとおりです。 Daggerは、AppComponentで指定されたOkHttpClientが必要であることを認識しています。したがって、これをどのように提供するかを調べます。コンストラクタに@Injectという注釈を付けたため、オブジェクト自体を構築できますか?より多くの依存関係が必要ですか?

この場合、このクライアントが提供されているコンポーネントのモジュールが検索されます。 getHttpClientに到達し、Cacheオブジェクトが必要であることを認識します。このオブジェクトがどのように提供されるかを再度調べます - コンストラクタインジェクション、別のプロバイダメソッド?

もう一度モジュールに用意されているので、getNetworkCacheに到達し、さらに別の依存関係が必要であることがもう一度わかります。

この動作は、HttpUrlなどの他の依存関係を必要としないオブジェクトに到達するまで続きます(getEndpoint)。

これが完了したら、OkHttpClientを作成することができます。

私はあなたの依存関係グラフにサイクルを持つことはできませんなぜそれがこのことから理解するのは簡単だと思う - それはBBAに依存に依存している場合は、オブジェクトAを作成することはできません。それで、いくつかの奇妙な理由から、そのモジュールのOkHttpClientに依存するgetEndpointというメソッドに達すると想像してください。これはうまくいかないでしょう。あなたは決して終わりに達しないサークルに行くだろう。

私はあなたの質問を理解しています:必要な入力を得るために各シングルトンを呼び出すことなく依存グラフ全体をどのように使用しますか?

そうではありません。シングルトンを取得するには、すべてのメソッドを呼び出す必要があります。少なくとも同じコンポーネント/スコープ内でそれらが提供されるのは初めてです。その後、コンポーネントの同じインスタンスを保持する限り、スコープ依存性は常に同じインスタンスを返します。ダガーがこれを確認します。何らかの理由でコンポーネントを破棄したり再作成したりする場合、依存関係は同じインスタンスにはなりません。詳細情報here。実際、これはすべてのスコープに当てはまります。単に@Singletonではありません。

しかし、あなたが正しいことを言っている限りは、アプリケーションが作成されると、コンポーネントが作成され、キャッシュされます。その後、メソッドcomponent()を使用するたびに常に同じコンポーネントが返され、スコープ依存性は常に同じになります。

+0

私はそれを理解し、それを使用しています。私がSpringに依存性注入を行うと、思考プロセスや実装によって自分自身を設定する必要性を変えることは困難でした。ダガーがたった一回の呼び出しで多すぎることは本当にクールです。私はあなたに完全な答えをアップアップしました。 –

関連する問題