2016-12-03 10 views
5

Klasa składników Dagger2 zawiera 3 moduły, których próbuję użyć do wstrzyknięcia zależności polowych do klasy aktywności Androida. Wygenerowany plik komponentu zawiera komentarze, że wszystkie moduły są nieużywane, łącząc ten numer page, aby uzyskać więcej informacji.Dagger2 - "Nieużywane" moduły w generowanej klasie komponentów

Moja klasa aktywności nazywa metodę wstrzykiwania (działania) składnika i ma pola z przypisami do iniekcji, które są dostarczane przez moduły, więc nie mam pewności, dlaczego wygenerowany plik komponentu nie ma żadnych dostawców do wykonania tego wstrzyknięcia.

Mój kod jest poniżej, dzięki za pomoc!

Generated Klasa Komponent:

public final class DaggerMainComponent implements MainComponent { 
     private DaggerMainComponent(Builder builder) { 
     assert builder != null; 
     } 

    public static Builder builder() { 
    return new Builder(); 
    } 

    public static MainComponent create() { 
    return builder().build(); 
    } 

    @Override 
    public void inject(Activity activity) { 
    MembersInjectors.<Activity>noOp().injectMembers(activity); 
    } 

    public static final class Builder { 
    private Builder() {} 

    public MainComponent build() { 
     return new DaggerMainComponent(this); 
    } 

    /** 
    * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://google.github.io/dagger/unused-modules. 
    */ 
    @Deprecated 
    public Builder daoModule(DaoModule daoModule) { 
     Preconditions.checkNotNull(daoModule); 
     return this; 
    } 

    /** 
    * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://google.github.io/dagger/unused-modules. 
    */ 
    @Deprecated 
    public Builder repositoryModule(RepositoryModule repositoryModule) { 
     Preconditions.checkNotNull(repositoryModule); 
     return this; 
    } 

    /** 
    * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://google.github.io/dagger/unused-modules. 
    */ 
    @Deprecated 
    public Builder portableModule(PortableModule portableModule) { 
     Preconditions.checkNotNull(portableModule); 
     return this; 
    } 
    } 
} 

Non-Generated Klasa Komponent:

@Component(modules={DaoModule.class,RepositoryModule.class,PortableModule.class}) 
public interface MainComponent { 
    void inject(Activity activity); 
} 

Moduł Klasy: Czy jest jakiś problem z posiadaniem jednego modułu zapewniają obiekt z zależność od innego obiektu dostarczanego przez inny moduł należący do tego samego komponentu?

@Module 
public class DaoModule { 

    private DatabaseHelper databaseHelper; 

    public DaoModule(DatabaseHelper databaseHelper){ 
     this.databaseHelper = databaseHelper; 
    } 

    @Provides 
    public Dao<Player,Integer> providePlayerDao(){ 
     return databaseHelper.getPlayerDao(); 
    } 

    @Provides 
    public Dao<GamePlayed,Integer> provideGamePlayedDao() { 
     try { 
      return databaseHelper.getDao(GamePlayed.class); 
     } catch (SQLException e) { 
      return null; 
     } 
    } 

    @Provides 
    public Dao<GamePlayer,Integer> provideGamePlayerDao() { 
     try { 
      return databaseHelper.getDao(GamePlayer.class); 
     } catch (SQLException e) { 
      return null; 
     } 
    } 
} 

... 

@Module 
public class RepositoryModule { 

    @Provides 
    public IGameResultRepository provideGameResultRepository(
      Dao<Player,Integer> playerDao, 
      Dao<GamePlayed,Integer> gameDao, 
      Dao<GamePlayer, Integer> gamePlayerDao) 
    { 
     return new OrmliteGameResultRepository(playerDao,gameDao,gamePlayerDao); 
    } 
} 

@Module 
public class PortableModule { 

    @Provides 
    public GameResultListener provideGameResultListener(IGameResultRepository gameResultRepository){ 
     return new GameResultListener(gameResultRepository); 
    } 

} 

Zastosowanie Klasa:

public class AppStart extends Application { 

    private MainComponent mainComponent; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     DatabaseHelper databaseHelper = new DatabaseHelper(getApplicationContext()); 

     mainComponent = DaggerMainComponent.builder() 
       .daoModule(new DaoModule(databaseHelper)) 
       .build(); 
    } 

    public MainComponent getMainComponent(){ 
     return mainComponent; 
    } 
} 

aktywny Klasa:

public class MyActivity extends Activity { 

    @Inject GameResultListener gameResultListener; 
    @Inject Dao<Player,Integer> dao; 
    @Inject IGameResultRepository repository; 


    @Override 
    protected void onCreate(Bundle state) { 
     super.onCreate(state); 

     ((AppStart)this.getApplication()).getMainComponent().inject(this); 
+0

Jaka jest twoja wersja Dagger – EpicPandaForce

+0

Możliwy duplikat [Dagger 2.2 składnik metody modułu budowniczy przestarzałe ] (http://stackoverflow.com/questions/36521302/dagger-2-2-component-builder-module-method-deprecated) –

Odpowiedz

3

Pytanie 1: Dlaczego moje moduły są oznaczone jako "nieużywany"?

Nie dostarczyłeś prawidłowego miejsca wstrzyknięcia! W obecnej wersji interfejs komponentu jest jednym z jedynym miejscem wykonywania wstrzyknięć pod numerem android.app.Activity. Ponieważ android.app.Activity nie ma adnotacji @Inject na swoich polach, otrzymujesz wtryskiwacz typu "nie-op". Podobnie, twoje moduły są oznaczone jako nieużywane, ponieważ żadna z nich nie jest faktycznie używana jako źródło zależności dla android.app.Activity. Aby rozwiązać ten problem, w zmianie podzespołów:

void inject(Activity activity); 

do:

void inject(MyActivity myActivity); 

Pytanie 2:

Czy jest jakiś problem z posiadające jeden moduł stanowić przedmiot z zależnością na innym obiekcie dostarczonym przez inny moduł należący do tego samego komponentu?

Nie, to jest w porządku.Aby zilustrować, weźmy prosty wykres obiektu:

public class Foo { 

    public Foo(FooDependency fooDependency) {} 
} 

public class FooDependency { 

    FooDependency(String name) {} 
} 

Chcemy, aby wprowadzić go do środka następnej klasy za pomocą Dagger:

public class FooConsumer { 

    @Inject Foo foo; 

    private FooConsumer() {} 
} 

Chcielibyśmy ponownie użyć modułu wiążącego FooDependency tak będziemy pisać dwa oddzielne moduły:

@Module 
public class FooModule { 

    @Provides 
    Foo foo(FooDependency fooDependency) { 
     return new Foo(fooDependency); 
    } 
} 

@Module 
public class FooDependencyModule { 

    @Provides 
    FooDependency fooDependency() { 
     return new FooDependency("name"); 
    } 
} 

i następujący komponent interfejsu:

@Component(modules = {FooModule.class, FooDependencyModule.class}) 
public interface FooComponent { 
    void inject(FooConsumer fooConsumer); 
} 

Wygenerowany komponent DaggerFooComponent zawiera następujący kod, który będzie poprawnie korzystać z FooDependency z oddzielnym modułem FooDependencyModule wstrzyknąć Foo:

@SuppressWarnings("unchecked") 
    private void initialize(final Builder builder) { 

    this.fooDependencyProvider = 
     FooDependencyModule_FooDependencyFactory.create(builder.fooDependencyModule); 

    this.fooProvider = FooModule_FooFactory.create(builder.fooModule, fooDependencyProvider); 

    this.fooConsumerMembersInjector = FooConsumer_MembersInjector.create(fooProvider); 
    } 
+1

Dzięki za odpowiedź na oba pytania. Wstrzyknięcia nie wykonywane dla podklas parametrów inject() są bardzo subtelne – win4fun

Powiązane problemy