Использование Dagger для внедрения зависимостей в конструкторы

Итак, я в настоящее время переделываю свое приложение для Android, чтобы использоватьКинжал, Мое приложение большое и сложное, и недавно я столкнулся со следующим сценарием:

Объект A требует специального экземпляра DebugLogger, который является идеальным кандидатом для внедрения. Вместо того, чтобы обойти регистратор, я могу просто вставить его через конструктор А. Это выглядит примерно так:

class A
{
    private DebugLogger logger;

    @Inject
    public A(DebugLogger logger)
    {
        this.logger = logger;
    }

    // Additional methods of A follow, etc.
}

Пока это имеет смысл. Тем не менее, A должен быть создан другим классом B. Несколько экземпляров A должны быть созданы, поэтому, следуя способу Даггера, я просто внедряюProvider<A> в Б:

class B
{
    private Provider<A> aFactory;

    @Inject
    public B(Provider<A> aFactory)
    {
        this.aFactory = aFactory;
    }
}

Хорошо, пока хорошо. Но подождите, внезапно A потребуются дополнительные входные данные, такие как целое число, называемое «количество», которое жизненно важно для его построения. Теперь мой конструктор для A должен выглядеть так:

@Inject
public A(DebugLogger logger, int amount)
{
...
}

Внезапно этот новый параметр мешает инъекции. Более того, даже если бы это сработало, у меня не было бы возможности передать «сумму» при получении нового экземпляра у провайдера, если я не ошибаюсь. Здесь я мог бы сделать несколько вещей, и мой вопрос: какой из них лучший?

Я мог бы рефакторинг А, добавивsetAmount() метод, который, как ожидается, будет вызван после конструктора. Однако это уродливо, потому что заставляет меня откладывать построение A до тех пор, пока не будет заполнено «количество». Если бы у меня было два таких параметра, «количество» и «частота», то у меня было бы два сеттера, что означало бы либо сложная проверка, чтобы убедиться, что конструкция A возобновляется после вызова обоих сеттеров, или мне пришлось бы добавить еще один третий метод в микс, например так:

(Somewhere in B):

A inst = aFactory.get();
inst.setAmount(5);
inst.setFrequency(7);
inst.doConstructionThatRequiresAmountAndFrequency();

Другой альтернативой является то, что я не использую инъекцию на основе конструктора и использую инъекцию на основе поля. Но теперь я должен обнародовать свои поля. Это не устраивает меня, потому что теперь я обязан раскрывать внутренние данные своих классов другим классам.

Пока что единственное элегантное решение, о котором я могу подумать, - это использовать инъекцию на основе поля для поставщиков, например:

class A
{
    @Inject
    public Provider<DebugLogger> loggerProvider;
    private DebugLogger logger;

    public A(int amount, int frequency)
    {
        logger = loggerProvider.get();
        // Do fancy things with amount and frequency here
        ...
    }
}

Тем не менее, я не уверен насчет сроков, так как я не уверен, будет ли Dagger вводить провайдер до вызова моего конструктора.

Есть ли способ лучше? Я что-то упускаю из-за того, как работает Dagger?

Ответы на вопрос(4)

Ваш ответ на вопрос