Кинжал 2 - нулевой указатель в полевой инъекции - PullRequest
0 голосов
/ 14 ноября 2018

Я использую кинжал 2 для внедрения зависимостей и застрял с инъекцией поля . Ниже приведен полный сценарий с примером кода:

Допустим, у нас есть класс A, который зависит от библиотеки B

class A {
    @Inject
    B b;
}

Модуль для B:

@Module
public class BModule {

    @Provides
    @Singleton
    public B provideB() {
        return new C.methodA();
        // C - static class; C.methodA returns B

    }
}

Но когда я пытаюсь использовать b в классе A, я получаю исключение нулевого указателя, но если я делаю то же самое, используя инъекцию в конструктор , тогда это работает отлично. Я могу заверить, что компонент и другие зависимости в порядке, так как часть конструктора работает правильно.

A - это зависимость некоторого другого класса (давайте назовем X), и A инициализируется с помощью инжекции в конструктор (протестировано). Также X вводится как void inject(X x);

У меня есть 2 вопроса:

  1. Есть ли что-то, что я пропускаю для полевого ввода, из-за которого это не вводится?
  2. Я могу успешно скомпилировать код и получить исключение во время выполнения, но dagger2 является DI времени компиляции, тогда почему он не может перехватить это во время компиляции?

P.S .: Я только что поделился частью кода, поскольку существует несколько зависимостей, поэтому просто пытаюсь объяснить сценарий. Дайте мне знать, если вопрос / сценарий все еще неясен или требуется дополнительная информация.

Спасибо.

1 Ответ

0 голосов
/ 14 ноября 2018

Инжекция поля в dagger немного сложнее, чем инжекция в конструктор.Когда вы используете инъекцию в конструктор вот так

class A {
    @Inject
    public A(B b) {}
}

и у вас есть провайдер для класса B

@Module
class DaggerModule {
    @Provides
    B provideB() {}
}

, теперь кинжал будет знать, как создать экземпляр A и передать ему требуемый параметр конструктора,Так что все в порядке, успешно компилируется и работает отлично.

Но если мы говорим о внедрении поля

class A {
    @Inject
    B b;
}

и у нас есть провайдер где-то для B, кинжал не может знать, как создатьA экземпляр и свойство Inject b при создании вручную экземпляра A вручную.Чтобы это работало, вам нужно написать специальный метод в компоненте

@Component(DaggetModule.class)
interface DaggerComponent {
    void inject(A a);
}

и где-нибудь в коде

A a = new A();
DaggerComponent component = //TODO getDaggerComponent()
component.inject(a);

После этого свойство b будет инициализировано и доступно для дальнейшего использования.Надеюсь, теперь понятно, как заставить работать полевую инъекцию.

...