Android Dagger - модули без конструктора без аргументов

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

Библиотека:

@Module(
    library = true
)
public class LibModule1 {

    private final String mString;

    public LibModule1(String string) {
        mString = string;
    }
    //... provide methods 
}

@Module(
    library = true,
    addsTo = LibraryModule1.class
)
public class LibModule2 {

    private final String mString;

    public LibModule2(String string) {
        mString = string;
    }
    //... provide methods 
}

Обратите внимание, что LibModule2 зависит от некоторых предоставленных объектов из LibModule1.

Приложение: в своем приложении я вставляю объекты из LibModule1 и LibModule2 в один класс. Но я не знаю, как я могу объединить эти модули. Параметр includes не работает, так как оба модуля не имеют конструктора без аргументов. addsTo не работает, потому что мне нужны оба библиотечных модуля, но параметр позволяет мне установить только один класс. Создание двух модулей приложения, внедряющих мой класс MyClass.class, не работает (класс может быть внедрен только одним модулем, верно?!).

@Module(
    injects = MyClass.class
)
public class AppModule {

}

Как я могу решить эту проблему?


person vRallev    schedule 05.02.2014    source источник


Ответы (2)


Вы можете полностью свободно передавать живые экземпляры модулей в ObjectGraph.create() и graph.plus(). Если у вас есть модули с состоянием, вы должны делать такие вещи, как:

ObjectGraph graph = 
    ObjectGraph.create(new LibraryModule1("foo"), LibraryModule2("bar));

Тем не менее, если вы создаете экземпляры библиотечных модулей, которые вы описываете в своем вопросе, таким образом, они все равно будут давать сбой во время компиляции, так как они, если вы не включите друг друга (или не пометите завершено-ложно). Вы можете просто включить LibModule2 в LibModule1, поскольку вы говорите, что у него есть объекты, которые зависят от объектов, предоставляемых последним.

@Module(library = true)
public class LibModule1 {

  private final String mString;

  public LibModule1(String string) {
    mString = string;
  }
  //... provide methods 
}

@Module(includes = LibraryModule1.class)
public class LibModule2 {

  private final String mString;

  public LibModule2(String string) {
    mString = string;
  }
  //... provide methods 
}

Я бы рекомендовал не использовать complete=false в сценарии, который вы описываете в своем вопросе, чтобы вы не избегали анализа графика. Вы должны использовать complete=false только в том случае, если вы создаете повторно используемый модуль, который ожидает состояние графа, которое он не может включить напрямую через другой модуль, потому что он будет объединен с модулем, личность которого неизвестна во время компиляции.

Вам следует делать то, что вы делаете здесь, только если вы планируете использовать LibModule2 в контексте альтернативы LibModule1. В приведенном выше случае нет особой причины не включать LibModule1 из LibModule2.

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

Вы должны использовать library=true только для указания того, что некоторые из предоставленных привязок предоставляются для использования другими зависимостями, а не для получения через graph.get(Foo.class) в качестве точек входа в граф. По сути, модули library=true исключаются из анализа потерянных привязок.

person Christian Gruber    schedule 06.02.2014
comment
Большое спасибо за подробное разъяснение. В документации я не нашел разницы между include и addsTo. Пожалуйста, поправьте меня, если я ошибаюсь: addsTo следует использовать только в том случае, если вы вызываете .plus() на другом ObjectGraph. Например. это используется для ObjectGraph с областью действий. Там вы вызываете plus() в Application ObjectGraph. Таким образом, модуль Activity использует addsTo. - person vRallev; 06.02.2014
comment
Ага. Мне нужно усилить некоторые документы по этим двум, хотя я надеялся получить аннотации пользовательских областей и усилить документы тогда. :/ - person Christian Gruber; 12.02.2014
comment
Общее примечание: если мы не ошиблись в нашем подходе, Dagger 2.0 не должен нуждаться в addTo, и у него будет совершенно другой механизм, который лучше, но у нас на это несколько месяцев. - person Christian Gruber; 12.02.2014

Извините, я сделал что-то не так. Теперь это работает.

Отвечая на мой собственный вопрос: вам нужно включить библиотечные модули.

@Module(
    injects = MyClass.class,
    includes = {LibModule1.class, LibModule2.class}
)
public class AppModule {

}

В одном модуле мне не хватало параметра complete = false.

person vRallev    schedule 05.02.2014
comment
Это не идеально, хотя и возможно. Вместо того, чтобы помечать LibModule2 как неполный и включать их в третий, вы можете просто включить LibModule1 в LibModule2. Вам следует делать то, что вы делаете здесь, только если вы планируете использовать LibModule2 в контексте альтернативы LibModule1. - person Christian Gruber; 06.02.2014