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。これはヘルプガイド以外は何もしません。
  • 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));

FactoryModuleBuilder.implementFactoryのファクトリメソッドのreturn型を具象クラスではなくインターフェイスにしたい場合を除いて、呼び出す必要はありません。そうすると、Guiceはあなたの助けなしに構築する具象型の種類を知りません。LoginService.Factory以下の例では、どの具体的なLoginService実装者をインスタンス化するかがわからないため、FactoryModuleBuilderに単純に実装するように依頼することはできません。

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));

それを除けば、 setterメソッドを作成するというconditの考えは悪くありませんが、それは部分的に初期化された状態でクラスを構築していることを意味します。

于 2013-01-30T22:09:18.303 に答える