Кинжал 2 метод инъекций? - PullRequest
0 голосов
/ 27 июня 2018

У меня есть 2 класса, для которых я хочу, чтобы внедрение зависимости происходило. В основном, для выполнения какой-либо задачи обоим нужны объекты друг друга.

Первый класс

public class AppMobilePresenter {
AppPresenter appPresenter;

@Inject
public AppMobilePresenter(AppPresenter appPresenter) {
    this.appPresenter = appCMSPresenter;
}
}

Его модуль

@Module
public class AppMobilePresenterModule {
@Provides
@Singleton
public AppMobilePresenter providesAppMobilePresenter(AppPresenter appPresenter) {
    return new AppMobilePresenter(appPresenter);
}
}

Второй класс

public class AppPresenter {
AppMobilePresenter appMobilePresenter;

@Inject
public AppPresenter() {
}

@Inject 
void setAppMobilePresenter(AppMobilePresenter appMobilePresenter){
    this.appMobilePresenter=appMobilePresenter;
}
}

Его модули

@Module(includes = { AppMobilePresenterModule.class})
public class AppPresenterModule {
@Provides
@Singleton
public AppPresenter providesAppPresenter() {
    return new AppPresenter();
}
}

У меня есть общий компонент для обоих

@Singleton
@Component(modules = {AppPresenterModule.class})
public interface AppPresenterComponent {
AppPresenter appPresenter();
}

После сборки компонента из моего класса приложения и запуска приложения я получаю нулевой объект AppMobilePresenter в классе AppPresenter. Есть ли что-то еще, что нужно сделать для внедрения метода.

1 Ответ

0 голосов
/ 27 июня 2018

Внедрение метода не происходит при вызове конструкторов, как в методах @Provides; если вы хотите, чтобы внедрение метода происходило, Dagger должен вызвать аннотированный конструктор @ в своем сгенерированном коде.

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

@Singleton
public class AppMobilePresenter {
  AppPresenter appPresenter;

  @Inject
  public AppMobilePresenter(AppPresenter appPresenter) {
    this.appPresenter = appCMSPresenter;
  }
}

@Singleton
public class AppPresenter {
  Provider<AppMobilePresenter> appMobilePresenterProvider;

  @Inject
  public AppPresenter(Provider<AppMobilePresenter> appMobilePresenterProvider) {
    this.appMobilePresenterProvider = appMobilePresenterProvider;
  }
}

Приведенный выше код может использовать ваш тот же компонент, и не требует никаких модулей . Единственное предостережение в том, что для доступа к AppMobilePresenter из AppPresenter вам нужно вызвать appMobilePresenterProvider.get(), который можно вызывать где угодно, кроме конструкторов и методов @Inject. Это решает проблему построения: в противном случае Dagger не смог бы создать AppMobilePresenter без предварительного создания AppPresenter и не смог бы создать AppPresenter без предварительного создания AppMobilePresenter. Однако он может создать провайдера и предоставить экземпляр при последующем вызове.

Если будущие читатели действительно нуждаются в внедрении поля или метода, они могут оставить ваши конструкторы и методы @Inject одними при удалении модулей и переключении на метод-инъекцию Provider<AppMobilePresenter>, что необходимо, поскольку внедрение метода имеет тот же порядок построения Цикл зависимости касается того, что делает инъекция конструктора.

...