2017-12-06 14 views
0

検索して、あまりにも多くのことを試した後、私は簡単な問題のように思えます。 以下は改造を注入する責任がある私のモジュールです。コンストラクタ・インジェクションとDagger2 2つの異なるクラスからの依存関係を注入する最適な方法

@Module 
public class NetworkingModule 
{ 
    @Provides 
    public Retrofit providesRetrofit() 
    { 
     Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); 
     Retrofit retrofit = new Retrofit.Builder() 
             .baseUrl(Constants.BASE_URL) 
             .addConverterFactory(GsonConverterFactory.create(gson)) 
             .build(); 

     return retrofit; 
    } 


} 

マイNetworkComponent

@Component(modules = NetworkingModule.class) 
public interface NetworkingComponent { 
    void inject(DashboardPresenterImpl target); 

    void inject(PicksPresenterImpl picksPresenter); 

    void inject(LoadsPresenterImpl loadsPresenter); 

    void inject(ShippingPresenterImpl shippingPresenter); 

    void inject(GeneralFilePresenterImpl generalFilePresenter); 
} 

ユーティリティクラス。このクラスにはAppPreferencesも注入されていることに注意してください。

public class AppUtils { 
    private Context context; 

    @Inject 
    AppPreferences preferences; 

    @Inject 
    public AppUtils(@ActivityContext Context context) 
    { 
     this.context = context; 

     /*ActivityComponent component = DaggerActivityComponent.builder() 
       .activityModule(new ActivityModule((Activity) context)) 
       .build(); 
     component.inject(this);*/ 
    } 
} 

は今、私のコードでは、私はこの

Class MyPresenterImpl{ 
@Inject 
    Retrofit retrofit; 

    @Inject 
    AppUtils appUtils; 
} 

示唆してください最適化し、上記目的を達成するための良い方法を達成したいです。

EDIT

追加AppPreference.java

public class AppPreferences { 
    @Inject 
    SharedPreferences sharedPreferences; 

    private SharedPreferences.Editor editor; 

    @Inject 
    public AppPreferences(@ActivityContext Context context) 
    { 
     ApplicationComponent component = DaggerApplicationComponent.builder() 
       .applicationModule(new ApplicationModule((Application) context.getApplicationContext())) 
       .build(); 
     component.inject(this); 

     editor = sharedPreferences.edit(); 
    } 

    public void putString(String key, String value) 
    { 
     editor.putString(key, value).commit(); 
    } 

    public String getString(String key) 
    { 
     return sharedPreferences.getString(key, null); 
    } 

} 

答えて

1

したいかどうかを決めてください。フィールドの注入やコンストラクタの注入を使用し、コンストラクタの注入を選択します。

public class AppUtils { 
    private Context context; 

    @Inject // field injection? 
    AppPreferences preferences; 

    @Inject // constructor injection? 
    public AppUtils(@ActivityContext Context context) 
    { 
    // ... 
    } 
} 

コンストラクタインジェクションを使用している場合、ダガーはフィールドを注入しません。後でそれを呼び出すこともできません。あなたのコンポーネントには、あなたのプレゼンターなどを注入するためのすべてのメソッドが含まれているべきではありません。

何かが必要な場合は、コンストラクタに入れます。

public class AppUtils { 
    private Context context; 
    private AppPreferences preferences; 

    @Inject // constructor injection! 
    public AppUtils(@ActivityContext Context context, AppPreferences preferences) 
    { 
    // ... 
    } 
} 

MyPresenterImplについても同様です。何かに依存している場合は、コンストラクタに入れ、コンストラクタに@Injectとマークして、Daggerが提供するすべての依存関係を持つオブジェクトを作成します。

あなたのコンポーネントには、Androidフレームワークタイプ(アクティビティ、フラグメント、...)以外には.inject(..)メソッドが含まれている必要があります。

私は最近、ダガーの使用についてsome general conceptsという記事を書きました。

+0

簡単な説明で素敵な答えをくれてありがとうが、私の主な質問はまだ答えられていない、つまりクラスMyPresenterImpl { @Inject 改造後の改造; @Inject AppUtils appUtils; } 上記を達成するために、最適化と良い方法を提案してください。「今、私がAppUtilsでコンストラクタインジェクションを使用しているところで、RetrofitがNetworkModuleによって誇張されています。 MyPresenterImplのための別のコンポーネントを作成せずに両方を注入する方法。ありがとう、あなたが共有したブログを読んでいます。 –

+0

'あなたのコンポーネントには、Androidフレームワークタイプ(アクティビティ、フラグメント、...)のみの.inject(..)メソッドが含まれている必要があります。 –

+0

非フレームワーク型は、いくつかのモジュールによって提供されるべきですので、コンストラクタインジェクションのみが必要です(inject()を呼び出す必要はありません) –

1

私の提案: コンテキストモジュールを作成します。

@Module 
public class ContextModule 
{ 
    Context context; 

    public ContextModule(Context context) { 
     this.context = context; 
    } 

    @Provides 
    @AppScope 
    Context context() { 
     return context; 
    } 
} 

@Module 
public class SharedPreferencesModule 
{ 

    @Provides 
    @AppScope 
    AppSharedPreferences provideAppSharedPreferences(Context context) { 
     return new AppSharedPreferences(context.getSharedPreferences("App",Context.MODE_PRIVATE)); 
    } 
} 
SharedPreferencesモジュールを作成します

同じようにあなたが

の代わりに、ネットワークのための独立したコンポーネントを作成する(AppUtils用など)に必要がある場合は、複数のモジュールを作成するアプリの1を作成することができます

@Component(modules = {ContextModule.class, NetworkingModule.class, SharedPreferencesModule}) 
public interface AppComponent {... 
+0

答えてくれてありがとう、本当にありがたいですが、このようにAppComponentをビルドしたいクラスは、DaggerAppComponentを構築する際にContextModule、NetworkingModule、およびSharedPreferencesのインスタンスを提供する必要があります。どちらが最適な方法ではないと思いますか。 –

+0

@eCDroid私の推奨するのは、1つのAppComponentインスタンスをApplicationクラスに格納して公開することです。任意のコンテキスト(Context.getApplicationContext())からアプリケーションオブジェクトを取得できるため、このコンポーネントに簡単にアクセスできます。 –

関連する問題