Dagger2: компонент не может зависеть от нескольких компонентов с областью действия.

Да, я знаю, что об этом уже спрашивали, и да, я знаю, что это "по задумке".

Но я хотел бы сделать что-то вроде этого:

@Component(modules = {RealmModule.class})
public interface RealmComponent {
    Realm realm();
}


@Component(modules = {RepositoryModule.class})
public interface RepositoryComponent {
    PersonRepository personRepository();

    ScheduleRepository schedulesRepository();
}

@Component(dependencies = {RealmComponent.class, RepositoryComponent.class})
public interface AppDataComponent
        extends RealmComponent, RepositoryComponent {
}

@ApplicationScope
@Component(dependencies = {AppContextComponent.class,
        AppDataComponent.class,
        AppDomainComponent.class,
        AppPresentationComponent.class,
        AppUtilsComponent.class})
public interface ApplicationComponent
        extends AppContextComponent, AppDataComponent, AppDomainComponent, AppUtilsComponent, AppPresentationComponent {
    void inject(CustomApplication customApplication);

    void inject(DashboardActivity dashboardActivity);
}

Однако то, что я получаю, является неограниченным, каждый раз, когда я ввожу JobManager или ScheduleRepository или что-то еще, я получаю новый экземпляр. Единственный способ, которым я мог "исправить" это, был это.

@Module
public class JobManagerModule {
    private JobManager jobManager;

    @Provides
    public JobManager jobManager(Context context) {
        if(jobManager == null) {
            jobManager = new JobManager(context, new Configuration.Builder(context).networkUtil(
                    new WifiOrMobileNetworkUtil(context)).build());
        }
        return jobManager;
    }
}

Не фанат.

Итак, как можно структурировать и разделить дерево зависимостей, без создания одного гигантского сверхбольшого компонента, в котором перечислены каждый модуль и каждое отдельное обеспечение? метод (вместо этих "подкомпонентных" зависимостей компонентов)?

Я пытался использовать для этого подкомпоненты, но тогда вам нужно предоставить каждый модуль для окончательного ApplicationComponent.

Я не уверен, что делать здесь. Я попытался указать @Singleton для каждого компонента первого уровня и @SubcomponentScope для каждого AppDataLevelComponent, я также попытался создать новую область действия для каждого отдельного подкомпонента, но оба они потерпели неудачу с «не может зависеть от нескольких компонентов области действия».

РЕДАКТИРОВАТЬ: По-видимому, чтобы получить провайдеров с областью действия, пометить компоненты областью действия недостаточно — вы также должны указать область действия для @Provides аннотированных методов.

@Module
public class RepositoryModule {
    @Provides
    @Singleton
    public PersonRepository personRepository() {
        return new PersonRepositoryImpl();
    }

    @Provides
    @Singleton
    public ScheduleRepository schedulesRepository() {
        return new SchedulesRepositoryImpl();
    }
}

Тем временем я закончил с этим übercomponent.

@Singleton
@Component(modules = {
        AppContextModule.class,
        DbMapperModule.class,
        DbTaskModule.class,
        RealmModule.class,
        RepositoryModule.class,
        InteractorModule.class,
        ServiceModule.class,
        PresenterModule.class,
        XmlPersisterModule.class
})
public interface ApplicationComponent
        extends AppContextComponent, AppDataComponent, AppDomainComponent, AppUtilsComponent, AppPresentationComponent {

Где классы xyzComponent - это просто интерфейсы для хранения методов обеспечения...

(Обратите внимание, что эта структура является антишаблоном, описанным Мартином Фаулером, и вы должны организовывать модули на основе функций/действий и превращать их в компоненты с подчиненной областью действия, используя зависимости компонентов. Зависимости компонентов используются для включения в состав ваших компонентов суперобласти и «наследования» поставщиков зависимостей.)


person EpicPandaForce    schedule 10.07.2015    source источник


Ответы (1)


У меня были те же проблемы, что и у вас, не так давно, и я закончил использовать тот же подход ubercomponent, за исключением того, что я использую @Subcomponents для организации вещей, а не для того, чтобы все модули были перечислены в ubercomponent (я называю это «верхним» или «компонентом приложения»).

Здесь вы можете увидеть пример: Как перенести отсутствующий инжект из модуля с complete = false с Dagger 1 на Dagger 2

person Ognyan    schedule 16.07.2015