Как обеспечить параметр для конструктора при выполнении инъекции конструктора? - PullRequest
0 голосов
/ 18 мая 2018

Я использую каркас dagger2 для внедрения зависимостей.

Как создать экземпляр объекта зависимости B (AND INJECT) с внедрением конструктора.Класс B имеет конструктор параметров.Пожалуйста, найдите пример ниже.

//This is class A, which is dependent on Class B.
//This has to create instance of B, with a (int) parameter.
class A {
    @Inject
    public B objectB;

    public A(int some_value){
        //This one I want to make it through dagger2
        //objectB = new B(some_value);

        BComponent bComponent = DaggerBComponent.builder().build();
        bComponent.provideB(this);
    }
}

//This is Class B, which has constructor injection.
//Constructor has a int parameter. 
class B {

    @Inject
    public B(int var){
        other_method(var);
    }
}

//This is dagger module, which provides Object B
@Module
public class BProvider {

    @Provides
    public B getB() {
        return new B();
    }
}

//This is dagger component, provide class-B dependency to class-A 
@Component(modules = {BProvider.class})
public interface BComponent {
    void provideB(A objA);
}

1 Ответ

0 голосов
/ 21 мая 2018

Из пояснений в комментариях:

Я пытаюсь использовать конструктор для достижения зависимости.ClassA зависит от ClassB.И у ClassB есть конструктор параметров, скажем, ClassB (int param).Этот параметр предоставляется во время выполнения, поэтому я путаюсь с тем, как кинжал может создать объект B.

Если параметр B каждый раз один и тот же, для графа вашего объекта

Это можетв этом случае ваш параметр является ключом, идентификатором или другим параметром конфигурации.Если это так, вы можете использовать метод @Provides в модуле , чтобы научить Dagger предоставлять объект ClassB при его запросе.

@Module
public abstract class YourModule {
  @Provides static ClassB provideClassB() {
    return new ClassB(/* your constant here */);
  }
}

Поскольку методы @Provides могутПринимая параметры, которые берутся из графа объектов, вы даже можете получить свое значение из другого места:

@Module
public abstract class YourModule {
  @Provides static ClassB provideClassB(SomeDependendency someDep) {
    return new ClassB(someDep.getParameterForClassB());
  }
}

Если B принимает только пользовательские параметры

Это может быть в том случае, если ваш ClassB являетсяобъект данных или одноразовый объект, особенно если вам не нужно заменять ClassB для тестирования.( Не насмехайтесь над объектами данных. ) Если все это так, ClassB не обязательно должен быть частью графа вашего объекта. Вызывать конструктор напрямую.

ClassB myB = new ClassB(someParameter);

Иногда это различие называется инъецируемые и новые : если у вас есть сложные и взаимосвязанные классы, которым нужен доступ друг к другу, у вас есть инъецируемый , и ссылки на него должны предоставляться извне.Если у вас плотно содержащийся класс, который не нуждается в подстановке, у вас есть newable , и вы можете напрямую вызывать конструктор или статический метод фабрики.

Если B имеет введенные параметры И конструкторпараметры

В некоторых случаях классу, подобному ClassB, необходимы одновременно параметры одноразового конструктора и введенные параметры из графика одновременно.Хотя это может быть тонким намеком на то, что класс делает слишком много, существуют общие обходные пути, которые объединяют эти два входа в один и тот же список параметров конструктора.Это известно как вспомогательная инъекция и позволяет создавать фабричные объекты , где структура DI предоставляет фабрику, и вы используете ее для получения нужного значения.

/* in ClassB */ public ClassB(DepA a, DepB b, int param) { /* ... */ }

/* ClassBFactory */
public ClassBFactory {
  Provider<DepA> depAProvider;
  Provider<DepB> depBProvider;
  public ClassBFactory(
      Provider<DepA> depAProvider,
      Provider<DepB> depBProvider) {
    /* set depAProvider and depBProvider */
  }

  public ClassB get(int param) {
    return new ClassB(depAProvider.get(), depBProvider.get(), param);
  }
}

Поскольку это аналогично генерации шаблонов для Dagger, но более пригодно для повторного использования в других средах внедрения зависимостей, Dagger рекомендует проект Google AutoFactory для генерации этой реализации на основе проверки зависимостейи классы.Вам нужно будет добавить несколько аннотаций в ClassB, чтобы это работало, но это позволит вам различать предоставляемые графом deps и одноразовые депо и защитит вас от необходимости изменять вызовы конструктора, если ваш список депонирования изменяется.

...