zzazzles
zzazzles

Reputation: 167

Is it necessary to manually inject into each class?

I'm trying to incorporate Dagger2 into my app, but the object I'm trying to inject is always null unless I manually call inject(). I thought inject() is necessary only for activities/services/fragments that are created by the system. Is it actually necessary to manually inject into all classes that have dependencies?

Here's my simple example:

public class Foo {
  @Inject Bar bar;
  ...
}

I have a module to provide Bar:

@Module
public final class BarModule {

  public BarModule() {}

  @Provides
  Bar provideBar () {
    return new Bar();
  }
}

And then I have a central component:

@Singleton
@Component(modules = {BarModule.class})
public interface AppComponent {
  Bar buildBar();
  void inject(Foo foo);
}

In my application, I build the component:

DaggerAppComponent.builder().barModule(new BarModule()).build();

But, bar is always null, unless I also call inject():

Foo foo = new Foo();
DaggerAppComponent.builder().barModule(new BarModule()).build().inject(foo);

Is it really necessary to define/call inject for every single class that has a dependency? I don't see such inject() calls everywhere in example code, so I'm thinking there's something I'm doing fundamentally wrong.

EDIT

Based on @DavidMedenjak's answer, I tried:

public class Bar {

    @Inject
    Bar() {}

    public int hello(int b) {
        return b + 5;
    }
}

Without a module or component, I now do:

Log.i(TAG, "Hello is " + bar.hello(5));

which returns an NPE because bar is null.

EDIT 2 I think the problem is that I didn't bootstrap the injection by creating the component and calling it. What I needed is:

AppComponent comp;
comp = DaggerAppComponent.create();
bar = comp.buildBar();

Which, for a one-level object, is non-sensical, but for a dependency chain, the component would create the rest of the objects in the chain.

Upvotes: 0

Views: 326

Answers (1)

David Medenjak
David Medenjak

Reputation: 34532

I thought inject() is necessary only for activities/services/fragments that are created by the system.

Correct.

Is it actually necessary to manually inject into all classes that have dependencies?

Nope. You should use constructor injection whenever possible.

  1. Get rid of BarModule. Avoid calling the constructor from @Provides annotated method), you don't need a module to use constructor injection
  2. Add @Inject to Bar's constructor to signal Dagger how to create the object

    class Bar {
      @Inject Bar() {}
    }
    

That's all there is to it. Dagger now knows how to create Bar. Add scopes & qualifiers to the class, dependencies as constructor parameters.

Upvotes: 2

Related Questions