4

我正在使用 guice 在我的构造函数中动态注入类。例如:

@Inject
public PublisherFrame(EventBus eventBus, MyPublisherService publishService)

在我的 guice 模块中:

bind(EventBus.class).in(Singleton.class);
bind(MyPublisherService.class).in(Singleton.class);

工作没有问题。

当我创建一个具有在 java 代码中构造的参数的对象时,问题就开始了:

public LoginController(EventBus eventBus, MyPublisherService publisherService, LoginDialog dlg)

这里 LoginDialog 是 java 代码创建的 java 类。为了解决这个问题,我使用@assist 并且:

install(new FactoryModuleBuilder().implement(ILoginController.class, LoginController.class).build(GuiceLoginControllerFactory.class));

工作也很好。但现在我必须创建 2 个额外的 java 文件:

  • LoginController 的新接口:ILoginController,它除了 help guice 什么都不做。
  • guice 的另一个接口:GuiceLoginControllerFactory

有没有更简单的方法来注入在构造函数中具有自定义参数的变量?(不创建 2 个额外的“guice”帮助文件)

4

1 回答 1

10

您实际上并不需要类本身的附加接口(见下文)。此外,我通常将我的工厂创建为它创建的类的嵌套接口:

public class LoginController {
  public interface Factory {
    LoginController create(LoginDialog dlg);
  }

  @Inject public LoginController(
      EventBus eventBus,
      MyPublisherService publisherService,
      @Assisted LoginDialog dlg) { /* ... */ }
}

// in your module
install(new FactoryModuleBuilder().build(LoginController.Factory.class));

除非您希望 Factory 的工厂方法的返回类型是接口而不是具体类,否则您不需要调用FactoryModuleBuilder.implement- 如果没有您的帮助,Guice 将不知道要构造哪种具体类型。在下面的示例中,您不能要求 FactoryModuleBuilderLoginService.Factory为您简单地实现,因为它不知道要实例化哪个具体的 LoginService 实现器:

interface LoginService {
  interface Factory {
    LoginService create(NetConnection connection);
  }
  boolean login(String username, String password);
}

class SimpleLoginService implements LoginService {
  @Inject SimpleLoginService(@Assisted NetConnection connection) { /* ... */ }
}

class SecuredLoginService implements LoginService {
  @Inject SecuredLoginService(
      EncryptionService encryptionService,
      @Assisted NetConnection connection) { /* ... */ }
}

// in your module: implements LoginService.Factory
install(new FactoryModuleBuilder()
    .implement(LoginService.class, SimpleLoginService.class)
    .build(LoginService.Factory.class));
// this one implements @Secured LoginService.Factory
install(new FactoryModuleBuilder()
    .implement(LoginService.class, SecuredLoginService.class)
    .build(Key.get(LoginService.Factory.class, Secured.class));

除此之外,condit创建 setter 方法的想法还不错,尽管这确实意味着您正在以部分初始化的状态构建您的类。

于 2013-01-30T22:09:18.303 回答