Нужно ли вводить вручную в каждый класс? - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь включить Dagger2 в свое приложение, но объект, который я пытаюсь внедрить, всегда null, если я не вызываю inject() вручную. Я думал, inject() необходимо только для действий / услуг / фрагментов, которые созданы системой. Действительно ли необходимо вручную внедрять все классы, которые имеют зависимости?

Вот мой простой пример:

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

У меня есть модуль для предоставления Bar:

@Module
public final class BarModule {

  public BarModule() {}

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

И тогда у меня есть центральный компонент:

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

В моем приложении я создаю компонент:

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

Но bar всегда null, если только Я также называю inject():

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

Действительно ли необходимо определять / вызывать инъекцию для каждого класса, который имеет зависимость? Я не вижу таких вызовов inject () везде в примере кода, поэтому я думаю, что я что-то делаю в корне неправильно.

EDIT

Основано на @ DavidMedenjak ответ, я пытался:

public class Bar {

    @Inject
    Bar() {}

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

Без модуля или компонента, я теперь делаю:

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

, который возвращает NPE, потому что бар ноль.

EDIT 2 Мне кажется, проблема в том, что я не сделал bootstrap инъекцию, создав компонент и вызвав его. Что мне нужно, это:

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

Что для одноуровневого объекта является бессмысленным, но для цепочки зависимостей компонент будет создавать остальные объекты в цепочке.

1 Ответ

2 голосов
/ 08 апреля 2020

Я думал, inject() необходимо только для действий / услуг / фрагментов, которые созданы системой.

Правильно.

Это на самом деле необходимо вручную внедрить во все классы, которые имеют зависимости?

Нет. Вы должны использовать инжектор конструктора всякий раз, когда это возможно.

  1. Избавьтесь от BarModule. Избегайте вызова конструктора из аннотированного метода @Provides), вам не нужен модуль для использования инжектора конструктора
  2. Добавьте @Inject в конструктор Bar, чтобы сообщить Даггеру, как создать объект

    class Bar {
      @Inject Bar() {}
    }
    

Это все, что нужно сделать. Кинжал теперь знает, как создать Bar. Добавьте области и квалификаторы к классу, зависимости как параметры конструктора.

...