Используя вспомогательную инъекцию, создайте сложное дерево зависимостей

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

public class AImpl implements A{

    @AssistedInject
    public AImpl(@Assisted Integer number, B b){

    }
}

public class BImpl implements B {

}

public class CImpl implements C {
    @AssistedInject
    public CImpl(A a){

    }
} 

заводской интерфейс:

public interface CFactory {
    C create(Integer number);
}

и модуль:

public class ABCModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(A.class).to(AImpl.class);
        bind(B.class).to(BImpl.class);

        install(new FactoryModuleBuilder().implement(C.class, CImpl.class).build(CFactory.class));
    }

    public static void main(String[] args) {
        Guice.createInjector(new ABCModule()).getInstance(CFactory.class).create(123);
    }

}

Выше происходит сбой со следующей трассировкой стека:

Исключение в потоке "основной" com.google.inject.CreationException: Ошибки создания Guice:

1) Не удалось найти подходящий конструктор в stack.AImpl. Классы должны иметь либо один (и только один) конструктор, аннотированный @Inject, либо конструктор без аргументов, который не является закрытым. в stack.AImpl.class(AImpl.java:12) в stack.ABCModule.configure(ABCModule.java:14)

2) stack.CImpl имеет конструкторы @AssistedInject, но ни один из них не соответствует параметрам в методе stack.CFactory.create(). Не удалось создать фабрику AssistedInject. при поиске stack.CImpl при поиске stack.C в stack.CFactory.create(CFactory.java:1)

2 ошибки в com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435) в com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:154) в com.google.inject.internal.InternalInjectorCreator .build(InternalInjectorCreator.java:106) в com.google.inject.Guice.createInjector(Guice.java:95) в com.google.inject.Guice.createInjector(Guice.java:72) в com.google.inject. Guice.createInjector(Guice.java:62) в stack.ABCModule.main(ABCModule.java:21)

Очевидно, это означает, что я слишком многого хочу от расширения — я надеялся, что инжектор будет искать глубоко в дереве зависимостей в поисках зависимости @Assisted. Есть ли способ сделать такой вспомогательный впрыск или мне нужно реализовать свою фабрику самостоятельно?


person macias    schedule 27.05.2013    source источник


Ответы (1)


В вашем коде есть пара проблем. Вам нужно ввести «A» в «C», но ваша фабрика настроена на ввод целого числа.

public interface CFactory {
    C create(Integer number);
}

Также я не думаю, что Guice предоставляет аннотацию @AssistedInject. Вместо этого используйте @Inject в конструкторе и отметьте параметры, которые вы хотите передать, с помощью @Assisted

person Joseph    schedule 25.12.2014
comment
У него нет проблем (за исключением того, что это в принципе невозможно сделать в Guice). Предполагается, что A и B автоматически вводятся Guice, в то время как я хотел получить фабрику, которая параметризует всю систему классов с параметром Integer (применяемым Guice к конструктору A). И да, есть аннотация @AssistedInject docs, иначе трассировка стека выглядела бы немного иначе. - person macias; 26.12.2014
comment
Я вижу, вы хотели, чтобы целое число было передано ближайшей зависимости, которая, я думаю, в этом нуждается. Ваш конструктор принимает A, а ваша фабрика передает ему целое число, поэтому я объяснял одну из ошибок, если вы не это имели в виду. - person Joseph; 26.12.2014