2017-02-27 4 views
0

J'ai commencé à configurer Dagger 2 et j'ai dû faire face à un problème étrange qui me semble être un bug.Les objets ne peuvent pas être fournis sans une méthode @ Provides-annotated

J'ai 1 composant principal et 1 sous-composant que j'ai 'plus' dans le composant parent.

J'utilise:

compile "com.google.dagger:dagger:2.4" 
apt "com.google.dagger:dagger-compiler:2.4" 
annotationProcessor "com.google.dagger:dagger-compiler:2.4" 

composant d'application est prety facile. Juste 'plus' du sous-composant:

@Singleton @Component(modules = { AristocratsAppModule.class }) 
public interface AristocratsAppComponent { 
    StreamComponent plus(StreamModule module); 
} 

Module d'application également tout à fait de base. Il fournit des dépendances au niveau des applications:

@Module public class AristocratsAppModule { 
    private static AristocratsApp app; 

    public AristocratsAppModule(AristocratsApp app) { 
    AristocratsAppModule.app = app; 
    } 

    @Provides @Singleton AristocratsApp providesApplication() { 
    return app; 
    } 

    @Provides @Singleton GsonXml providesGsonXml() { 
    return ... 
    } 

    @Provides @Singleton @Named("aristocrats") Retrofit providesAristocratsRetrofit() { 
    return ... 
    } 

    @Provides @Singleton @Named("last_fm") Retrofit providesLastFmRetrofit() { 
    return ... 
    } 
} 

sous-composants a deux StreamServices (services de retrofit) et injectez simple:

@PerController @Subcomponent(modules = { StreamModule.class }) public interface StreamComponent { 
    void inject(StreamsController streamsController); 

    AristocratsStreamService providesAristocratsStreamService(); 

    LastFmStreamService providesLastFmStreamService(); 
} 

Module de sous- fournit l'injection de présentateur et deux injections différentes de services d'amélioration:

@Module public class StreamModule { 
    private StreamsController mView; 

    public StreamModule(StreamsController view) { 
    mView = view; 
    } 

    @Provides @PerController StreamMvp.Presenter providesPresenter(StreamCase streamCase, 
     StreamModelMapper streamMapper) { 
    return new StreamPresenter(mView, streamCase, streamMapper); 
    } 

    @Provides @PerController AristocratsStreamService providesAristocratsStreamService(
     @Named("aristocrats") Retrofit retrofit) { 
    return retrofit.create(AristocratsStreamService.class); 
    } 

    @Provides @PerController LastFmStreamService providesLastFmStreamService(
     @Named("last_fm") Retrofit retrofit) { 
    return retrofit.create(LastFmStreamService.class); 
    } 
} 

Applicat injection d'ions que j'appelle à onCreate() de ma classe app:

mAppComponent = DaggerAristocratsAppComponent.builder() 
     .aristocratsAppModule(new AristocratsAppModule(this)) 
     .build(); 

Voir injection que j'appelle dans mon contrôleur:

getAppComponent().plus(new StreamModule(this)).inject(this); 

Exception que je reçois lors de la construction:

Error:(13, 8) error: [com.qsoft.streams.presentation.di.StreamComponent.inject(com.qsoft.streams.presentation.StreamsController)] com.qsoft.streams.data.network.AristocratsStreamService cannot be provided without an @Provides-annotated method. 
com.qsoft.streams.data.network.AristocratsStreamService is injected at 
com.qsoft.streams.data.network.StreamApi.<init>(…, streamServiceAristocrats, …) 
com.qsoft.streams.data.network.StreamApi is injected at 
com.qsoft.streams.data.repository.StreamRepository.<init>(streamApi, …) 
com.qsoft.streams.data.repository.StreamRepository is injected at 
com.qsoft.streams.domain.interactors.StreamCase.<init>(streamRepository) 
com.qsoft.streams.domain.interactors.StreamCase is injected at 
com.qsoft.streams.presentation.di.StreamModule.providesPresenter(streamCase, …) 
com.qsoft.streams.presentation.StreamMvp.Presenter is injected at 
com.qsoft.streams.presentation.StreamsController.mPresenter 
com.qsoft.streams.presentation.StreamsController is injected at 
com.qsoft.streams.presentation.di.StreamComponent.inject(streamsController) 
A binding with matching key exists in component: com.qsoft.streams.presentation.di.StreamComponent 

Les plaintes d'erreur sur @Provides-annotated method manquant mais ils sont à l'intérieur de mon module enfant. Il semble que Dagger2 ne les voit pas. Je pensais que le problème pourrait être dans la déclaration manquante de AristocratsStreamService dans le sous-composant, donc je l'ai même ajouté là mais rien n'a changé. Cette situation semble très étrange et j'aimerais entendre quelques contributions de développeurs expérimentés de Dagger2.

Merci d'avance!

Répondre

0

J'ai remarqué que vous n'avez pas défini de partie de sous-composants dans AristrocratsModule.

Ce:

@Module public class AristocratsAppModule { 

dans ce:

@Module(subcomponents = {StreamComponent.class}) 
public class AristocratsAppModule { 

Essayez de faire les modifications suivantes. Dans votre StreamComponent, créez un générateur.

@Subcomponent.Builder 
interface Builder { 
    Builder streamModule(StreamModule module); 

    StreamComponent build(); 
} 

Finalement, vous injectera tout via StreamComponent, et il injectera tout AristocratsAppComponent aussi bien.

public StreamComponent getStreamComponent(Controller controller) { 
    return getAppComponent().streamBuilder().streamModule(new StreamModule(controller)).build(); 
} 

Plus chose peut être retiré après cela.

+0

J'ai essayé mais l'erreur est la même. Il ne l'a pas enlevé. – Val