6

我有一些使用工厂的示例代码。我想通过删除工厂来清理代码并改用 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();
     }
}

我将如何构造一个在修改后的 MailClient中MailImpl使用该对象的实例?config我应该以这种方式使用 Guice 吗?

4

3 回答 3

3

看看AssistedInject。它似乎解决了这个问题。

于 2010-01-21T08:51:05.490 回答
2

2个解决方案是可能的:1)将配置绑定为一个guice对象,包括它的主机参数。然后只需注入邮件,在您的主要方法中,您可以忽略邮件具有进一步依赖关系的事实。

2)必须为每次发送(收件人?)单独配置邮件。那么你别无选择,只能使用 MailFactory 自己创建。

于 2010-01-21T00:48:04.990 回答
0

您可以在 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(),并且 Bob 是您的叔叔。

请注意,必须绑定 getMailConfig 的参数。绑定String等常用类型时,一定要加上绑定注解。

于 2018-01-15T01:21:53.800 回答