Подтвердить что ты не робот

Кинжалы 2 вводят параметры конструктора

Я увидел следующий пример на веб-сайте Dagger 2:

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

и документация:

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

Когда я пишу модуль для предоставления Thermosiphon как

@Module
public class ThermosiphonModule {

    @Provides
    @Singleton
    Thermosiphon provideThermosiphon() {
        return new Thermosiphon(???);
    }

}

Конструктор Thermosiphon по-прежнему требует Heater в качестве аргумента, что делает "автоматическое вложение зависимостей конструктора" бесполезным.

Я пробовал

return new Thermosiphon(null); 

и

return new Thermosiphon(); 

(пустой конструктор) и надеялся, что Dagger2 заберет, что я хочу, чтобы отсутствующий Heater был введен, но нагреватель предоставленного Thermosiphon всегда имеет значение null;

Я проверил, хотя мой HeaterComponent/HeaterModule работает нормально и может предоставить Heater.

Неужели я не понимаю всю функцию "Кинжал", которая удовлетворяет зависимостям конструктора для вас? или я что-то упускаю?

4b9b3361

Ответ 1

Если вы используете модули, то если у вас есть два модуля поставщика, привязанные к одному и тому же компоненту, то вы сможете разрешить им видеть нагреватель в качестве параметра конструктора.

@Module
public class HeaterModule {
    @Provides
    @Singleton
    Heater heater() {
        return new Heater(); // if not using @Inject constructor
    }
}

@Module
public class ThermosiphonModule {
    @Provides
    @Singleton
    Thermosiphon thermosiphon(Heater heater) {
        return new Thermosiphon(heater); // if not using @Inject constructor
    }
}

@Singleton
@Component(modules={ThermosiphonModule.class, HeaterModule.class})
public interface SingletonComponent {
    Thermosiphon thermosiphon();
    Heater heater();

    void inject(Something something);
}

public class CustomApplication extends Application {
    private SingletonComponent singletonComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        this.singletonComponent = DaggerSingletonComponent.builder().build(); //.create();
    }

    public SingletonComponent getSingletonComponent() {
        return singletonComponent;
    }
}

Но при инсталляции конструктора вы также сможете предоставлять объекты этой заданной области видимости или объекты без объекта, если у них есть конструктор @Inject.

Например,

@Singleton
@Component // no modules
public interface SingletonComponent {
    Thermosiphon thermosiphon();
    Heater heater();

    void inject(Something something);
}

и

@Singleton
public class Heater {
    @Inject
    public Heater() {
    }
}

и

@Singleton
public class Thermosiphon {
    private Heater heater;

    @Inject
    public Thermosiphon(Heater heater) {
        this.heater = heater;
    }
}

или

@Singleton
public class Thermosiphon {
    @Inject
    Heater heater;

    @Inject
    public Thermosiphon() {
    }
}

Ответ 2

Во-первых, поскольку вы аннотировали конструктор Thermosiphon с помощью @Inject, вам не нужен метод @Provides. Dagger использует этот конструктор для создания экземпляра, когда это необходимо. Просто выделите класс Thermosiphon с помощью @Singleton, чтобы сохранить поведение singleton.

Если вы хотите использовать метод @Provides и полностью ответить на свой вопрос, вы можете указать Heater в качестве параметра для метода:

@Module
public class ThermosiphonModule {

    @Provides
    @Singleton
    Thermosiphon provideThermosiphon(Heater heater) {
        return new Thermosiphon(heater);
    }

}