2017-08-08 1 views
2

Le problème est que Dagger ne peut pas voir la dépendance (DataManager) que je veux utiliser dans ActivityModule qui est défini dans ApplicationModule. J'ai assez standard structure du projet Dagger2:Dagger2 ne peut pas voir la méthode avec l'annotation @Provide définie dans un autre module. Ne peut pas être fourni sans méthode @ fournit annotée

ActivityComponent.java:

@PerActivity 
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) 
public interface ActivityComponent { 
    void inject(WelcomeFragment fragment); // HERE ERROR IS COMING FROM 
} 

ApplicationComponent.java:

@Singleton 
@Component(modules = ApplicationModule.class) 
public interface ApplicationComponent { 
    Context getContext(); 
} 

ActivityModule.java:

@Module 
public class ActivityModule { 

    private Activity activity; 

    public ActivityModule(Activity activity) { 
     this.activity = activity; 
    } 

    @Provides 
    CompositeDisposable provideCompositeDisposable() { 
     return new CompositeDisposable(); 
    } 

    @Provides 
    @PerActivity 
    WelcomeViewModel provideWelcomeViewModel(DataManager dataManager, CompositeDisposable compositeDisposable) { 
     return new WelcomeViewModel(dataManager, compositeDisposable); 
    } 
} 

ApplicationModule.java:

@Module 
public class ApplicationModule { 

    private final Application application; 

    public ApplicationModule(Application application) { 
     this.application = application; 
    } 

    @Provides 
    Context provideContext() { 
     return application; 
    } 

    @Provides 
    @Singleton 
    DataManager provideDataManager(DataManagerImpl dataManager) { 
     return dataManager; 
    } 

    @Provides 
    @Singleton 
    Retrofit provideRetrofit() { 
     return new Retrofit.Builder() 
       .baseUrl(<API_ADDRESS>) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
       .build(); 
    } 
} 

PerActivity.java:

@Scope 
@Retention(RetentionPolicy.RUNTIME) 
public @interface PerActivity { 
} 

L'erreur apparaît dans WelcomeFragment où je suis en train de injectentWelcomeViewModel que besoins DataManager an d est le message qui indique que Poignard peut voir où DataManager est fourni :

Error:(12, 10) error: <PACKAGE_NAME>.data.DataManager cannot be provided without an @Provides-annotated method. 
<PACKAGE_NAME>.data.DataManager is injected at 
<PACKAGE_NAME>.di.module.ActivityModule.provideWelcomeViewModel(dataManager, …) 
<PACKAGE_NAME>.views.welcome.WelcomeViewModel is injected at 
<PACKAGE_NAME>.views.welcome.WelcomeFragment.viewModel 
<PACKAGE_NAME>.views.welcome.WelcomeFragment is injected at 
<PACKAGE_NAME>.di.component.ActivityComponent.inject(fragment) 

WelcomeViewModel.java:

public class WelcomeViewModel extends ViewModel { 

    @Inject 
    public WelcomeViewModel(DataManager dataManager, CompositeDisposable compositeDisposable) { 
     super(dataManager, compositeDisposable); 
    } 

(...) 
} 

WelcomeFragment.java:

public class WelcomeFragment extends BaseFragment { 
    @Inject WelcomeViewModel viewModel; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     view = inflater.inflate(R.layout.fragment_welcome, container, false); 
     getActivityComponent().inject(this); 
     init(); 
     return view; 
    } 
(...) 
} 

DataManagerImpl.java:

@Singleton 
public class DataManagerImpl implements DataManager { 
    private Retrofit retrofit; 

    @Inject 
    public DataManagerImpl(Retrofit retrofit) { 
     this.retrofit = retrofit; 
    } 
(...) 
} 

Je ne peux dire que je suis en utilisant la même structure de poignard dans 2 autres projets et toujours qu'il travaillait sans aucun problème.

Répondre

1

Puisque vous utilisez Component dependencies vous devez exposer le DataManager dans le ApplicationComponent au ActivityComponent

@Singleton 
@Component(modules = ApplicationModule.class) 
public interface ApplicationComponent { 
    Context getContext(); 

    DataManager exposeDataManager(); 
} 
+0

Wow, je ne savais pas que je dois faire. Merci beaucoup! – user3448282

+0

Vous pouvez utiliser [Subcomponents] (https://google.github.io/dagger/subcomponents) à la place - vous n'avez donc pas besoin des méthodes d'exposition. – TmTron

+0

Merci, je vais lire à ce sujet. – user3448282