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

Я экспериментирую с " новой " поддержкой Android в Dagger 2.
Я хочу настроить следующую архитектуру в Dagger:

Приложение => Деятельность => Контроллер ( Проводник)

(Контроллер в основном View это создается системой. Вы можете думать об этом как Fragment но без поддержки Dagger Injection)

Для каждого уровня я определил зависимость: ApplicationDep, ActivityDep а также ControllerDep,

  1. мой Controller должен быть в состоянии внедрить все эти зависимости.
  2. мой Activity должен быть в состоянии ввести ApplicationDep и ActivityDep
  3. мой Application должен быть в состоянии только ввести ApplicationDep

Все работает кроме моего Controller,
Я не могу ввести ActivityDep,

public class MyController extends Controller {
  @Inject
  ApplicationDependency applicationDependency;
  //@Inject
  //ActivityDependency activityDependency; // can not be provided
  @Inject
  ControllerDependency controllerDependency;

  @NonNull @Override protected View onCreateView(@NonNull LayoutInflater layoutInflater, @NonNull ViewGroup viewGroup) {
    ConductorInjection.inject(this);
    return layoutInflater.inflate(R.layout.controller_main, viewGroup, false);
  }
}

В настоящее время у меня есть мой ControllerBindingModule привязан к моему ApplicationComponent Однако это должно быть связано с Activity для того, чтобы он также был доступен в Controller,
Как я могу это сделать?

@Singleton
@Component(modules = {
        ApplicationModule.class,
        ActivityBindingModule.class,
        AndroidSupportInjectionModule.class,

        ConductorInjectionModule.class,
        ControllerBindingModule.class
})
interface AppComponent extends AndroidInjector<App> {
    @Component.Builder
    abstract class Builder extends AndroidInjector.Builder<App> {}
}

Полный код можно найти на Github.
Благодарю.

1 ответ

Решение

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

Во-первых, для Activity инъекции.
Controller не является подкомпонентом Appcomponentтак нужно только ActivityBindingModule,

AppComponent.java

@Singleton
@Component(modules = {
        AppModule.class
        ActivityBindingModule.class,
        AndroidSupportInjectionModule.class,
})
interface AppComponent {
    @Component.Builder
    abstract class Builder extends AndroidInjector.Builder<App> {}
}

По той же причине нам нужно только реализовать HasActivityInjector в App,

App.java

public class App extends Application implements HasActivityInjector {
    @Inject protected DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingActivityInjector;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerAppComponent
            .builder()
            .create(this)
            .inject(this);
    }
}

Потому что мне нужно объявить Controller как подкомпонент ActivityComponent, Я использую шаг 2 и шаг 3 в документации Dagger о введении объектов деятельности

Измени свой ActivityBindingModule

ActivityBindingModule.java

@Module(subcomponents = {MainActivityComponent.class})
public abstract class ActivityBindingModule {

    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity>
    bindYourActivityInjectorFactory(MainActivityComponent.Builder builder);
}

Создать ActivityComponent,

MainActivityComponent.java

@Subcomponent(modules = {MainActivityModule.class})
@ActivityScope
public interface MainActivityComponent extends AndroidInjector<MainActivity>{
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
}

Затем пришло время установить контроллер в качестве подкомпонента компонента деятельности.
добавлять ControllerBindingModule.class в MainActivityComponent,

@Subcomponent(modules = {MainActivityModule.class, ControllerBindingModule.class})
@ActivityScope
public interface MainActivityComponent extends AndroidInjector<MainActivity>{
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
}

И реализовать HasControllerInjector в MainActivity,

MainActivity.java

public class MainActivity extends AppCompatActivity implements HasControllerInjector {

    @Inject protected DispatchingAndroidInjector<Controller> dispatchingControllerInjector;

    @Override
    public DispatchingAndroidInjector<Controller> controllerInjector() {
        return dispatchingControllerInjector;
}

Не нужно менять другие файлы, и то, что вы хотите, сделано.

Другие вопросы по тегам