Dagger2 - вставить значение в @Module без использования конструктора - PullRequest
0 голосов
/ 16 января 2020

После видеоуроков CodingInFlow по Dagger, я дошел до того, что вижу использование @BindsInstance внутри @ Component.Builder.

Наличие следующих классов:

Класс модели:

public class DieselEngine implements Engine {
    private static final String TAG = "Car";

    private int horsePower;

    @Inject
    public DieselEngine(int horsePower) {
        this.horsePower = horsePower;
    }

    @Override
    public void start() {
        Log.d(TAG, "Diesel engine started. Horsepower = " + horsePower);
    }
}

Модули:

@Module
public class DieselEngineModule {

    private int horsePower;
//
//    public DieselEngineModule() {
//
//    }
//
//    @Provides
//    int provideHorsePower(@Named("dieselParam") int horsePower) {
//        return horsePower;
//    }

    public DieselEngineModule(int horsePower) {
        this.horsePower = horsePower;
    }

    @Provides
    int provideHorsePower(int horsePower) {
        return horsePower;
    }

//    We no longer need to manually instantiate DieselEngine obj using "new DieselEngine(horsePower)".
//    Because we created a "provideHorsePower()" method, and we @Inject-ed the constructor of
//    DieselEngine "DieselEngine(int horsePower){..}" so that the provideHorsePower() can inject into it.
    @Provides
    Engine provideEngine(DieselEngine dieselEngine) {
        return dieselEngine;
    }
}
public abstract class PetrolEngineModule {

//    @Provides
//    Engine provideEngine(PetrolEngine engine) {
//        return engine;
//    }

    @Binds
    abstract Engine bindEngine(PetrolEngine engine);

    // NOTE: abstract methods are never instantiated, so we can't use normal @Provides methods, only static @Provides methods


}

Компонент:

@Component(modules = {
        WheelsModule.class,
        DieselEngineModule.class,
        })
public interface CarComponent {

    Car getCar();

//    Dagger 2 does not inject fields automatically. It can also not inject private fields.
//    If you want to use field injection you have to define a method in your @Component interface
//    which takes the instance into which you would like Dagger 2 to inject an object into this field.
//    ex: all fields with @Inject from MainActivity will be injected once this method is used.
    void inject(MainActivity mainActivity);

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder horsePower(@Named("horse power") int horsePower);

        @BindsInstance
        Builder engineCapacity(@Named("engine capacity")int engineCapacity);

        @BindsInstance
        Builder moduleParam(@Named("dieselParam")int someNumber);

//        Builder dieselEngineModule(DieselEngineModule dem);

        // dagger will automaticaly implement this method, we just have to declare it, because
        // we are overwriting the builder definition
        CarComponent build();

    }

}

Мой вопрос: есть ли способ «впрыскивать» "переменная внутри PetrolEngineModule, чтобы сохранить ее там, без необходимости добавлять параметр в конструктор модуля (см. метод с комментариями в компоненте)?

например: int a; внутри PetrolEngineModule, который будет вставлен целым числом @Named ("dieselParam") из компонента. Так что он будет установлен только один раз, когда Модуль создается впервые.

Я экспериментировал с комментируемым методом в DieselEngineModule, где переменная @Named напрямую предоставляется из Компонента, в Для использования при предоставлении DieselEngine. Но это нормально? Я мог бы использовать некоторые советы здесь. Это то, что я хочу сделать? Использовать переменную @Named из графика компонентов / зависимостей вместо сохранения в модуле?

...