Just started using Dagger 2 today and I'm a bit confused on how exactly I need to set everything up.
I'm trying to inject a POJO, but it's always null.
First, some code:
App.java
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent
.builder()
.appModule(new AppModule(this))
.build();
}
public AppComponent component() {
return appComponent;
}
AppModule.java
@Module
public class AppModule {
private Application app;
public AppModule(Application app) {
this.app = app;
}
@Provides @Singleton
public Application application() {
return app;
}
}
AppComponent.java
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App application);
Application application();
}
NetworkingManager.java
@Singleton
public class NetworkingManager {
private Context ctx;
@Inject
public NetworkingManager(Context context) {
this.ctx = context;
}
}
NetModule.java
@Module
public class NetModule {
@Provides @Singleton
public NetworkingManager provideNetworkingManager(Application application) {
return new NetworkingManager(application);
}
}
NetComponent.java
@Singleton
@Component(modules = {NetModule.class},
dependencies = {AppModule.class})
public interface NetComponent {
void inject(NetworkingManager networkingManager);
}
SomeClass.java
@Inject
NetworkingManager networkingManager;
public void doSomethingWithNetworkManager() {
networkManager.doStuff();
}
I've spent a good deal of time looking through lots of tutorials, SO questions, and examples, but I haven't been able to figure out what I'm doing wrong.
I'm 99% certain I have something setup wrong, but I haven't been able to figure out what.
Based on your comment, you want to make NetworkingManager
available everywhere in your application.
Let's start with your definition of the Component
:
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App application);
}
This tells Dagger that this component will be injecting the App
class. Now here you can also tell Dagger other classes you would like to inject. So if you want to also inject an Activity
for example you would add:
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App application);
void inject(MainActivity activity) //Where MainActivity is a class that extends Activity.
}
Please note that this is not the best way, IMO, to share Application wide dependencies; you should create a Component
that inherits from AppComponent
and make AppComponent
expose the desired shared dependencies.
Now let's look at your module class:
@Module
public class NetModule {
@Provides @Singleton
public NetworkingManager provideNetworkingManager(Application application) {
return new NetworkingManager(application);
}
}
Here you are @Provide
ing a NetworkingManager
, that is fine. Your NetworkingManager
requires an Application
(a Context
really), why not provide App
inside of NetworkingManager
?, or even better why not provide NetworkingManager
inside the AppModule
since AppModule
should @Provide
things that are common for the whole Application
:
@Module
public class AppModule {
private Application app;
public AppModule(Application app) {
this.app = app;
}
@Provides @Singleton
public Application application() {
return app;
}
@Provides @Singleton
public NetworkingManager provideNetworkingManager(Application application) {
return new NetworkingManager(application);
}
}
Now inside your App
class:
public class App extends Application {
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent
.builder()
.appModule(new AppModule(this))
.build();
appComponent.inject(this);
}
public AppComponent component() {
return appComponent;
}
}
And in our hypothetical MainActivity
:
public class MainActivity extends Activity {
private AppComponent appComponent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appComponent = ((App)getApplicationContext()).getAppComponent();
appComponent.inject(this);
}
}
It seems that you are not using @Component(dependencies = {...})
correctly. dependencies
is used when you want to expose a dependency from one Component
to another using the mechanism I mentioned above.