I am familiar with Spring dependency injection, but Dagger2 is new to me. I am trying to get a simple java application working but field injection does not work.
I have a class Main
, that depends on a class MainBusiness
which in turn depends on MainDao
.
MainBusiness
gets injected into Main
fine, but MainDao
does not get injected into MainBusiness
and throws a NullPointerException
.
Here is the MainDao
that implements an interface
IMainDao
public class MainDao implements IMainDao
{
@Inject
public MainDao()
{
}
public String getResource()
{
return "This is the resource you are looking for";
}
}
Here is the MainBusiness
that implements IMainBusiness
public class MainBusiness implements IMainBusiness
{
// package friendly field.
@Inject
IMainDao mainDao;
@Inject
public MainBusiness()
{
}
public String getResource()
{
return mainDao.getResource(); // throws NPE here.
}
}
Here is the AppModule
@Module
public class AppModule
{
/**
* Provides a singleton instance of the MainDao
*
* @return
*/
@Provides
@Singleton
public IMainDao providesMainDao()
{
return new MainDao();
}
/**
* Provides a singleton instance of the MainBusiness Class
*
* @return
*/
@Provides
@Singleton
public IMainBusiness providesMainBusiness()
{
return new MainBusiness();
}
}
The AppComponent
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent
{
/**
* @param main
*/
void inject(Main main);
}
And the Main
class
public class Main
{
@Inject
IMainBusiness mainBusiness;
public Main()
{
AppComponent dac = DaggerAppComponent.builder().build();
dac.inject(this);
}
public static void main(String args[])
{
Main main = new Main();
System.out.println(main.mainBusiness.getResource());
}
}
It throws an NPE on MainBusiness.getResource(MainBusiness.java:14)
What am I missing here? Appreciate any help I can get.
P.S This is a plain Java
application. It is not an Android
application.
Field injection will inject the fields of the object you pass in.
someComponent.inject(someObject)
will then inject the fields ofsomeObject
, but it does not inject the dependencies transitively. HenceMainBusiness
will still have an uninitialized DAO.If you call
new MainBusiness();
yourself you can't expect Dagger to take care of it. You should use constructor injection, and not callnew
yourself. Modules are for bindings, or additional setup, and should reduce the boilerplate of calling all the constructors yourself.I took some liberty to switch to constructor injection and completely remove field injection, since it is not needed for your use case. (Maybe there's some typo, I did not compile it)
I suggest that you have another look at some guides to make sure you understand the concepts, or you might be creating more work for yourself than necessary. I also wrote a post recently where I try to clear up some misconceptions about Dagger.