I'm having a hard time wrapping my head around how to use Dagger 2.0 outside of the limited examples I've seen. Let's take an example reading application. In this reading app, there is a library of a user's stories and the ability to Log in. The classes of interest for the purpose of this example are:
MainApplication.java
- extends Application
LibraryManager.java
- Manager which is responsible for adding/removing stories in the user's library. This is called from the MainApplication
AccountManager.java
- Manager which is responsible for saving all a user's login information. It can be called from the LibraryManager
I'm still trying to wrap my head around what Components and Modules I should be creating. Here's what I can gather so far:
Create a HelperModule
that provides an AccountManager
and LibraryManager
instance:
@Module
public class HelperModule {
@Provides
@Singleton
AccountManager provideAccountManager() {
return new AccountManager();
}
@Provides
@Singleton
LibraryManager provideLibraryManager() {
return new LibraryManager();
}
}
Create a MainApplicationComponent
that lists the HelperModule
in its list of modules:
@Singleton
@Component(modules = {AppModule.class, HelperModule.class})
public interface MainApplicationComponent {
MainApplication injectApplication(MainApplication application);
}
Include @Injects LibraryManager libraryManager
in the MainApplication
and inject the application into the graph. Finally it queries the injected LibraryManager
for the number of stories in the library:
public class MainApplication extends Application {
@Inject LibraryManager libraryManager;
@Override
public void onCreate() {
super.onCreate();
component = DaggerMainApplicationComponent.builder()
.appModule(new AppModule(this))
.helperModule(new HelperModule())
.build();
component.injectApplication(this);
// Now that we have an injected LibraryManager instance, use it
libraryManager.getLibrary();
}
}
Inject the AccountManager
into the LibraryManager
public class LibraryManager {
@Inject AccountManager accountManager;
public int getNumStoriesInLibrary() {
String username = accountManager.getLoggedInUserName();
...
}
}
However the problem is that the AccountManager
is null when I try to use it in the LibraryManager
and I don't understand why or how to solve the problem. I'm thinking that it's because the MainApplication
that was injected into the graph doesn't use the AccountManager directly, but then do I need to inject the LibraryManager
into the graph some how?
modify your classes as follow and it would work:
your POJO:
public class LibraryManager {
@Inject AccountManager accountManager;
public LibraryManager(){
MainApplication.getComponent().inject(this);
}
public int getNumStoriesInLibrary() {
String username = accountManager.getLoggedInUserName();
...
}
...
}
your component Interface:
@Singleton
@Component(modules = {AppModule.class, HelperModule.class})
public interface MainApplicationComponent {
void inject(MainApplication application);
void inject(LibraryManager lm);
}
}
your application Class :
public class MainApplication extends Application {
private static MainApplicationComponent component;
@Inject LibraryManager libraryManager;
@Override
public void onCreate() {
super.onCreate();
component = DaggerMainApplicationComponent.builder()
.appModule(new AppModule(this))
.helperModule(new HelperModule())
.build();
component.injectApplication(this);
// Now that we have an injected LibraryManager instance, use it
libraryManager.getLibrary();
}
public static MainApplicationComponent getComponent(){return component;}
}
In fact, you need to do the same for all of your dependent classes, basically you have access to the application class in all Activity sub-classes so making get component as an static method is none-less. but for POJO u need to catch the component somehow. there are a lot of way to implement. this is just an illustration to give u the idea how it works. now you can destroy the mars :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With