2017-06-24 3 views
0

私はFragmentのプレゼンターをコンストラクタインジェクションによって注入しようとしています(プレゼンターのために@Providesメソッドを作成する必要はありません)。Dagger2コンストラクタの注入が機能しない

は、私はそれを正しくやっていることを信じて、私はまだ、次のエラーが発生します:

MainFragmentPresenterは@ Provides-または@作成し、注釈方法なしに提供することはできません。ここで

は私の設定です:

ApplicationComponent.java

@Singleton 
@Component(
     modules = { 
       NetworkModule.class 
     } 
) 
public interface ApplicationComponent { 

    NetworkService networkService(); 
} 

MainFragmentComponent.java

@PerFragment 
@Component(
     dependencies = ApplicationComponent.class, 
     modules = MainFragmentPresenterModule.class 
) 
public interface MainFragmentComponent { 

    MainFragmentView view(); 

    void inject(MainFragment mainFragment); 
} 

MainFragmentPresenterModule.java

@Module 
public class MainFragmentPresenterModule { 

    private final MainFragmentView _view; 

    public MainFragmentPresenterModule(MainFragmentView view) { 
     _view = view; 
    } 

    @Provides 
    @PerFragment 
    MainFragmentView provideMainFragmentView() { 
     return _view; 
    } 
} 

NetworkModule.java

@Module 
public class NetworkModule { 

    @Provides 
    @Singleton 
    OkHttpClient provide_OkHttpClient() { 
     return new OkHttpClient(); 
    } 

    @Provides 
    @Singleton 
    OpenWeatherEndpoints provide_OpenWeatherAPI(OkHttpClient client) { 

     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl("http://api.openweathermap.org/data/2.5/") 
       .addConverterFactory(GsonConverterFactory.create()) 
       .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
       .client(client) 
       .build(); 

     return retrofit.create(OpenWeatherEndpoints.class); 

    } 

    @Provides 
    @Singleton 
    YoutubeEndpoints provide_YoutubeEndpoints(OkHttpClient client) { 

     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl("https://www.googleapis.com/youtube/v3/") 
       .addConverterFactory(GsonConverterFactory.create()) 
       .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
       .client(client) 
       .build(); 

     return retrofit.create(YoutubeEndpoints.class); 

    } 

    @Provides 
    @Singleton 
    NetworkService provide_NetworkService(OpenWeatherEndpoints openWeatherEndpoints, YoutubeEndpoints youtubeEndpoints) { 
     return new NetworkService(openWeatherEndpoints, youtubeEndpoints); 
    } 
} 

PerFragment.java

@Scope 
@Retention(RUNTIME) 
@interface PerFragment { 
} 

MainFragmentPresenterImpl.java

public class MainFragmentPresenterImpl implements MainFragmentPresenter { 
    private final MainFragmentView _view; 
    private NetworkService _service; 

    @Inject MainFragmentPresenterImpl(MainFragmentView view, NetworkService networkService) { 
     _view = view; 
     _service = networkService; 
    } 
} 

そして、私は私のフラグメントでプレゼンターを注入しようとすると...

public class MainFragment extends Fragment implements MainFragmentView { 

    public static final String TAG = "MainFragment"; 

    @Inject 
    MainFragmentPresenter _presenter; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     DaggerMainFragmentComponent.builder() 
       .applicationComponent(WeatherForecastApp.get(getContext()).getAppComponent()) 
       .mainFragmentPresenterModule(new MainFragmentPresenterModule(this)) 
       .build() 
       .inject(this); 
    } 
} 

すべてのヘルプは大歓迎です!ありがとう。

答えて

1

MainFragmentPresenterImplからMainFragmentPresenterへのバインディングを追加する必要があります。 Daggerはタイプ間でキャストしないので、@Bindsメソッドで明示的に行う必要があります。 @Bindsは引数を返す@Providesメソッドと同等ですが、より効率的に実装されています。ただ、このようなあなたのモジュールを変更します。また

@Module 
public abstract class MainFragmentPresenterModule { 
    ... 
    @Binds 
    abstract MainFragmentPresenter(MainFragmentPresenterImpl impl); 
} 

、あなたは@Provides方法、_viewフィールド、および@BindsInstanceを使用して、モジュール内のコンストラクタを取り除くことができます。

DaggerMainFragmentComponent.builder() 
    .applicationComponent(WeatherForecastApp.get(getContext()).getAppComponent()) 
    .mainFragmentView(this) 
    .build() 
    .inject(this); 
:あなた、あなたのモジュールは、コンストラクタを持っていないので、あなたは、このようなコンポーネントを構築することができるように

public interface MainFragmentComponent { 
    @Component.Builder 
    interface Builder { 
     @BindsInstance 
     Builder mainFragmentView(MainFragmentView mainFragmentView); 
    } 
    void inject(MainFragment mainFragment); 
} 

さて、ダガーは、インスタンスを提供する必要はありません。

関連する問題