I am trying to inject a singleton
repository into a Foo
class to use it.
the repo
is not injected and still null, why am i missing some annotation or that's not the proper way
Repository.java
@Singlton
public class Repository {...}
Foo.java
public class Foo {
@Inject Repository repo;
}
Dagger works via Components: Specifically, you pass Dagger the list of things you want or that you want to do (Component interfaces) as well as how you want to provide non-trivial dependencies (Modules), and then Dagger generates an implementation of your interface that does what you want.
You've shown us Foo and its dependency Repository, but if you haven't shown us the Component, I'm guessing that you might not have one. At this point you can choose how to proceed: you can either get your Foo from a Dagger Component, or you can create your Foo as you usually do and then call inject(foo)
to inject a particular Foo instance with all of its @Inject
fields (including your Repository). The former is usually preferred to make a straightforward interface, but the latter works well with objects where you don't control the lifecycle (like Android's Application, Activity, Fragment, Service, and other similar objects).
If you choose to let Dagger create your Foo, you'll need to create an @Inject
-annotated constructor (even an empty one) for both Foo and Repository, then write a Component like this:
@Component public interface YourComponent {
Foo createFoo(); // Name this whatever you like; it's a factory because
// of its return type and lack of parameters.
}
Excellent! Now as long as you have an implementation of YourComponent, you could create a Foo and inject it. You haven't written an implementation, but if you did, it might look like this:
public YourComponentImpl implements YourComponent {
@Override public Foo createFoo() {
Foo foo = new Foo();
foo.repo = new Repository();
return foo;
}
}
However, you don't have to write one: Dagger will write one that is equivalent to the one above for you as soon as you compile the YourComponent interface with the Dagger compiler, which means compiling it with javac
with the Dagger compiler specified as a source code processor. Dagger works as an annotation processor that reads the @Component
interface and generates a class called DaggerYourComponent. After that, you can get an instance by calling the static method DaggerYourComponent.create()
, and then on that instance call yourComponent.createFoo()
wherever you'd otherwise call new Foo()
.
To inject, you follow a similar pattern as above, except your method should take one argument (your existing Foo instance), and consequently you don't need to add an @Inject
-annotated constructor onto Foo because Dagger doesn't ever construct one. You do for Repository, though, because Dagger will create that.
@Component public interface YourComponent {
void inject(Foo foo); // Name this whatever you like; it's a members injector
// because it takes exactly one argument.
}
This will allow you to call DaggerYourComponent.create()
like above to create your component, and then call yourComponent.inject(foo)
to inject a Repository into the repo
field you annotated.
Once you get more familiar with Dagger, you can start to build off of what you know and add Modules, inject with Provider<>
injections, or add scopes so you can reuse instances rather than creating new ones each time. Check the User's Guide for more.