Почему использование @ Module.subcomponents лучше, чем установка подкомпонента с помощью метода на родительском компоненте? - PullRequest
0 голосов
/ 08 апреля 2019

Из документов :

Использование @Module.subcomponents лучше, поскольку оно позволяет Dagger определять, запрашивается ли субкомпонент когда-либо.Установка подкомпонента с помощью метода на родительском компоненте является явным запросом для этого компонента, даже если этот метод никогда не вызывается.Кинжал не может обнаружить это и поэтому должен генерировать субкомпонент, даже если вы никогда его не используете.

Кто-нибудь точно понимает, что это значит?

1 Ответ

2 голосов
/ 09 апреля 2019

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

@Component(modules = YourModule.class)
public interface YourComponent {
  ClassA a();
  ClassB b();

  ExplicitSubcomponent createExplicitSubcomponent(Dep1 dep1, Dep2 dep2);
}

@Module(subcomponents = ImplicitSubcomponent.class)
public abstract class YourModule {
  @Binds ClassC classC(DefaultClassC classCImpl);
}

В приведенном выше примере у нас есть ClassA, ClassB и ClassC. Допустим, что из всех этих вам нужен только класс A: они фактически не зависят друг от друга, и вы фактически не используете подкомпоненты.

  • Dagger реализует связывание для транзитивного замыкания зависимостей ClassA и ClassA, и это хорошо, потому что вам это нужно! Вы помещаете его в интерфейс компонента, чтобы Dagger мог создавать реализации для вас, включая все зависимости ClassA.
  • Dagger реализует привязку для ClassB, но в этом нет необходимости, но Dagger не может сказать: он знает только, что определено b(), поэтому кто-нибудь может позвонить и попросить ClassB когда-нибудь. Кинжал не знает, вызывает ли кто-нибудь b(), поэтому он должен создавать и ссылаться на фабричные реализации для ClassB, и все, от чего ClassB транзитивно зависит.
  • Dagger не реализует привязку для ClassC, потому что , даже если вы ее связали, никто не запрашивает ее . Он недоступен в интерфейсе, и никто не просит его внутри, поэтому Dagger может его опустить.

Это иллюстрирует философию Даггера, заключающуюся в компиляции только того, что достижимо из самого интерфейса компонента. Это относится и к подкомпонентам:

  • Dagger создает реализацию для ExplicitSubcomponent, потому что, как и в случае с ClassB, вы привязали его к интерфейсу. Кто-то может попросить об этом.
  • Dagger не создает реализацию для ImplicitSubcomponent, пока он не будет доступен из ClassA или ClassB. Как только вы это сделаете, это так. Если никто не запрашивает ImplicitSubcomponent, Dagger не генерирует код для него.

Конечно, если вы урезаете свою сборку с помощью Proguard или другого статического анализатора, эти инструменты могут обрезать ненужные классы или методы. Однако в этот момент вы выполняете работу по кодированию подкомпонента, вы выполняете работу по его компиляции в байт-код, а затем Proguard выполняет работу по его удалению. В больших проектах это намного эффективнее, если вы избегаете компиляции подкомпонента, пока не узнаете, что он вам нужен, что позволяет Module.subcomponents.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...