Инъектор конструктора с использованием Guice - PullRequest
6 голосов
/ 21 января 2010

У меня есть пример кода, который использует фабрики. Я хотел бы очистить код, удалив фабрики и вместо этого использовать Guice. Я попытался сделать это, но я столкнулся с небольшим блокпостом. Я действительно новичок в Guice, так что я надеюсь, что кто-то может помочь мне здесь.

Существующий клиентский код (с использованием фабрик):

public class MailClient {

    public static void main(String[] args) {
        MailConfig config = MailConfigFactory.get();
        config.setHost("smtp.gmail.com");
        Mail mail = MailFactory.get(config);
        mail.send();
    }
}

Моя попытка рефакторинга с помощью Guice:

//Replaces existing factories
public class MailModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Mail.class)
        .to(MailImpl.class);

        bind(MailConfig.class)
        .to(MailConfigImpl.class);
    }
}

public class MailImpl implements Mail {

    private final MailConfig config;

    @Inject
    public MailImpl(MailConfig config) {
        this.config = config;
    }

    public void send() { ... }
}

public class MailClient {

    public static void main(String[] args) {
        MailModule mailModule = new MailModule();
        Injector injector = Guice.createInjector(mailModule);
        MailConfig config = injector.getInstance(MailConfig.class);
        config.setHost("smtp.gmail.com");
        Mail mail = //??
        mail.send();
     }
}

Как мне создать экземпляр MailImpl, используя объект config в моем исправленном MailClient? Должен ли я использовать Guice таким образом?

Ответы [ 3 ]

3 голосов
/ 21 января 2010

Взгляните на AssistedInject . Похоже, для решения этой проблемы.

2 голосов
/ 21 января 2010

2 решения возможны: 1) также связать конфиг как объект guice, включая его параметр host. затем просто введите Mail, в вашем основном методе вы не можете игнорировать тот факт, что почта имеет дополнительные зависимости.

2) почта должна быть настроена индивидуально для каждого отправителя (получатель?). тогда у вас нет выбора, но создайте его самостоятельно, используя MailFactory.

0 голосов
/ 15 января 2018

Вы можете сделать все в MailModule следующим образом:

public class MailModule extends AbstractModule {
    @Override
    protected void configure() {
       ... // other bindings
    }

    @Provides
    MailConfig getMailConfig( ... ) {
        MailConfig config = new MailConfig( ... );
        config.setHost("smtp.gmail.com");
        config;
    }
}

Если вам нужен одноэлементный MailConfig, добавьте аннотацию @Singleton в getMailConfig () и Боб станет вашим дядей.

Обратите внимание, что аргументы getMailConfig должны быть связаны. При связывании часто используемых типов, таких как String, обязательно добавьте аннотацию привязки.

...