Reputation: 650
I'm new to dagger. I created a very simply unit test to try to understand how I should use dagger. Unfortunately it fails. I've probably not understood some basic principles of dagger.
public class A {
@Inject
public B b;
public B getB() {
return b;
}
}
public class B {
}
@Module(injects = { A.class, B.class })
public class DaggerModule {
@Provides
public A provideA() {
return new A();
}
@Provides
public B provideB() {
return new B();
}
}
and my test class which fails
public class DaggerTest extends TestCase {
public void testDagger() {
ObjectGraph theGraph = ObjectGraph.create(new DaggerModule());
A theA = theGraph.get(A.class);
assertNotNull(theA.getB());
}
}
I thought that dagger would inject B into A since A wants it to be injected and DaggerModule contains a @Provides annotated method which creates B.
Update:
I found that when I write the module class like this
@Module(injects = { A.class })
public class DaggerModule {
@Provides
public B provideB() {
return new B();
}
}
the injection of B into A works. However I do not understand why it is not working when the module has a Provides annotated method which construct an instance of A. In that case the only way to get the injection to work is to actually write the injection yourself like:
@Module(injects = { A.class, B.class })
public class DaggerModule {
@Provides
public A provideA(B b) {
A theA = new A();
theA.b = b;
return theA;
}
@Provides
public B provideB() {
return new B();
}
}
or to create a constructor in A which accepts B so that you can write
@Module(injects = { A.class, B.class })
public class DaggerModule {
@Provides
public A provideA(B b) {
return new A(b);
}
@Provides
public B provideB() {
return new B();
}
}
This need for having a constructor or setter in A which accepts B was just the kind of overhead I thought could by avoided by using Dagger.
So I'm I doing something wrong or did I misinterpreted the capabilities of dagger?
Upvotes: 0
Views: 830
Reputation: 474
I noticed exactly the same behaviour, i.e. @Provides produced instances don't get their @Inject marked members injected. cf Dagger & nested injections
I did exactly the same as you: use @Provides parameters injection to forward to the constructor (without the same impression that it kind of defeats dagger's purpose). I'll try to dive a bit more into dagger to figure out if this is a normal behaviour as soon I have some spare time.
Upvotes: 1
Reputation: 3675
If you make Class A the entry point of your module than dagger will inject dependecy B to A.
@Module(entryPoints = { A.class })
public class DaggerModule {
@Provides
public A provideA() {
return new A();
}
@Provides
public B provideB() {
return new B();
}
}
Upvotes: 0