2016-08-16 25 views
5

Mam zatem ApplicationComponent do wstrzykiwania singletonów do moich fragmentów i prezenterów, ale próbuję utworzyć komponent do wstrzyknięcia do tego samego prezentera, który AppComponent robi. Coś w tym stylu.Jak używać Daggera 2 do wstrzykiwania z użyciem wielu komponentów do tego samego obiektu?

@Component{modules = FileManagerModule.class} 
public interface FileManagerComponet 
{ 
    public void inject(MyPresenter presenter); 
} 

@Component{modules = AppModule.class} 
public interface AppComponent 
{ 
    public void inject(MyPresenter presenter); 
} 

@Module 
public class AppModule 
{ 
    private Context appContext; 
    @Provides 
    @Singleton 
    public SharedPreferences preferences() 
    { 
     return appContext.sharedPreferences(); 
    } 
    ... 
} 

@Module 
public class FileManagerModule 
{ 
    private Context activityContext; 
    @Provides 
    public FileManager FileManager() 
    { 
     return new FileManager(activityContext); 
    } 
    ... 
} 
+2

To pytanie było zadawane wielokrotnie, komponent musi podawać _wszystkie pola lub nie zadziała. Nie można mieszać i dopasowywać komponentów. na przykład sprawdź tutaj: http://stackoverflow.com/a/38897722/1837367 –

+0

@DavidMedenjak Następnie jak mogę nadać FileManagerModule kontekst działania, jeśli AppComponent jest budowany, gdy aplikacja jest tworzona i nie ma kontekstu aktywności? – Stampede10343

Odpowiedz

6

Dla każdego, kto nie może tego zrozumieć, jeden komponent musi dostarczyć wszystkie zależności do obiektu. Tak więc w moim przypadku musiałbym uczynić komponent FileManagerComponent subkomponentem i ".plus()" go z moim AppComponentem, lub uczynić go zależnym od AppComponent i mieć AppComponent eksponować Context downstream, mając metodę Context context();, która pozwoli komponenty, które od niego zależą mieć dostęp do kontekstu, który ma.

Na przykład:

@Singleton 
@Component(modules = {NetworkModule.class, AndroidModule.class}) 
public interface ApplicationComponent { 
    FileManagerComponent plus(FileManagerModule module); 
} 

@Subcomponent(modules = {FileManagerModule.class}) 
public interface FileManagerComponent { 
    void injectMyActivity(MyFileManagingActivity activity); 
} 

I będzie go używać tak (w MyFileManagingActivity):

FileManagerComponent fmc = applicationComponent.plus(new FileManagerModule()); 
fmc.injectMyActivity(this); 

Albo jeśli nie chcesz używać Podskładniki coś takiego:

@Singleton 
@Component(modules = {NetworkModule.class, AndroidModule.class}) 
public interface ApplicationComponent { 
    Context context(); 
    File applicationRootDirectory(); 
} 

// Notice this is ALSO a Component 
@Component(modules = {FileManagerModule.class}, dependencies = ApplicationComponent.class) 
public interface FileManagerComponent { 
    void inject(MyFileManagerActivity activity); 
} 

Teraz musisz zbudować komponent, który zależy od składnika aplikacji.

FileManagerComponent fmc = DaggerFileManagerComponent.builder() 
        .applicationComponent(appComponent) 
        .fileManagerModule(new FileManagerModule()) 
        .build(); 
fmc.inject(this); 
+2

proszę dodać kod –

+0

Byłoby wspaniale, gdyby można było dodać kod tutaj. Ponieważ oficjalne dokumenty i przykłady podskładników są zbyt trudne do zrozumienia –