Как создать экземпляр объекта с динамическими членами с помощью Dagger2?

У меня есть класс, который получает аргументы в конструкторе:

public class Dependency{
  Dependency(int number1, int number2, int number3, DependencyListener listener){}     
}

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

Кроме того, как мне использовать метод @Inject в этом случае?

Изменить 1

@ jeff-bowman Я думал об использовании следующего метода:

@Module public class DependencyModule {
  int first;
  int second;
  int third;
  DependencyListener listener;

  public DependencyModule(int first, int second, int third, DependencyListener listener) {
    this.first = first;
    this.second = second;
    this.third = third;
    this.listener = listener
  }

  @Provides Dependency provideDependency(int first, int second, int third, DependencyListener listener) {
    return new Dependency(first, second, third, listener)
  }
}

@Component(modules = { DependencyModule.class }) public interface     
DependencyComponent {
  void inject(DependentClass1 target);
  void inject(DependentClass2 target);
  void inject(DependentClass3 target);
}

и в каждом DependentClass я бы сделал:

public class DependentClass{
  @Inject Dependency;
  public DependentClass{
      DaggerDependencyComponent.builder().dependencyModule(new DependencyModule(first, second, third, this)).build().inject();
  }
}

Это хорошая практика?


person danidin    schedule 15.02.2017    source источник


Ответы (1)


Концептуально вам нужна фабрика:

/** Inject this wherever you want an instance of Dependency. */
public interface DependencyFactory {
  Dependency create(
      int number1,
      int number2,
      int number3,
      DependencyListener listener);
}

public class DependencyFactoryImpl implements DependencyFactory {
  @Inject Provider<SomeDaggerDepIfNeeded> someDaggerDepProvider;

  @Override public void create(
      int number1,
      int number2,
      int number3,
      DependencyListener listener) {
    return new Dependency(number1, number2, number3, listener,
        someDaggerDepProvider.get() /* if necessary */);
  }
}

Однако, поскольку это так легко сгенерировать автоматически, для этого часто есть встроенные инструменты. Guice называет это Assisted Injection и предоставляет FactoryModuleBuilder (через необязательное расширение JAR), который автоматически создает фабрики во время выполнения. Dagger 2 не имеет встроенного эквивалента, в основном потому, что Google уже выпустил генератор фабрик JSR-330 с открытым исходным кодом под названием AutoFactory, который создает фабрику для любого JSR-330, включая Dagger, Guice и Spring.

@AutoFactory
public class Dependency{
  Dependency(
      int number1, int number2, int number3, DependencyListener listener,
      @Provided SomeDaggerDepIfNeeded somedaggerDep){}     
}

См. документацию AutoFactory для получения подробной информации о его вызовах, особенно если вы заинтересованы в том, чтобы сгенерированная фабрика реализовывала интерфейс. Использование интерфейса, который вы определяете явно, может упростить работу с созданным кодом в IDE.

(Если у вас нет необходимости в зависимостях от Dagger или в замене других реализаций этого класса классами, которые зависят от него, вы можете оставить класс таким, какой он есть, и обращаться с вызовом new как с фабрикой.)

person Jeff Bowman    schedule 15.02.2017
comment
Выглядит красиво, но AutoFactory имеет 15507 методов, в основном из-за Guava. Это огромное количество методов, которые библиотека может использовать в Android. Что вы думаете о том, как я хотел использовать это в редактировании, которое я опубликовал? будет ли это хорошей практикой? или есть какие-то улучшения, которые я должен сделать? - person danidin; 16.02.2017
comment
В вашей технике отдельных компонентов нет ничего изначально неправильного, но здесь это излишне. AutoValue на самом деле не использует Guava в своих сгенерированных зависимостях, они просто собраны вместе прямо сейчас. см. контекст и обходные пути здесь. - person Jeff Bowman; 16.02.2017