32
votes

I am trying to get Dagger up an working on my project.

However I get the following exception on one of my classes during compilation:

error: No injectable members on Foo. Do you want to add an injectable constructor?

However, the class have no dependencies and as such uses the default no-arg constructor:

public class Foo
{
    ...
}

Do I really have to add an injectable no-arg constructor like below?

public class Foo
{
     @Inject
     public Foo()
     {
     }

     ....
}
1

1 Answers

41
votes

From the docs:

Classes that lack @Inject annotations cannot be constructed by Dagger.

Dagger actively requires you to add @Inject to your injectable class, either by adding a no-args constructor, or adding an injectable field. The third option is to return the class from an @Provides method like so:

@Module(...)
class MyModule {
  @Provides Foo provideFoo() {
    return new Foo(); // Foo is not injectable.
  }
}

This does seem like extra boilerplate, but from experience with Guice and other frameworks, JIT binding of random classes turns out to be rife with error. We have seen java.lang.String injected into things, and because someone forgot to bind it, you ended up with "" injected instead of the desired string. Dagger, therefore, requires an @Inject constructor, or field.(Guice optionally has this in 4.x, though for backwards compatibility, it is off by default)

This is one rare instance where Dagger has chosen more correctness guarantees at the cost of some small amount of verbosity.