Да, я знаю, что об этом уже спрашивали, и да, я знаю, что это "по задумке".
Но я хотел бы сделать что-то вроде этого:
@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
- это просто интерфейсы для хранения методов обеспечения...
(Обратите внимание, что эта структура является антишаблоном, описанным Мартином Фаулером, и вы должны организовывать модули на основе функций/действий и превращать их в компоненты с подчиненной областью действия, используя зависимости компонентов. Зависимости компонентов используются для включения в состав ваших компонентов суперобласти и «наследования» поставщиков зависимостей.)