17

Guiceを使用してプロジェクトのリファクタリングを試みます。アイデアは、すべての言語インターフェースをフランス語ポーランド語のようなconcreateオブジェクトにバインドすることです。

バインディング用のモジュールがあります。

public class StandardModule extends AbstractModule {

    @Override
    protected void configure() {

       bind(Language.class).to(Polish.class);

    }
 }

そして、この注入されたオブジェクトを使用するクラス(AboutDialog.java):

@Inject Language language;

public AboutDialog(JFrame parent) {
    super(parent, "", true);
    this.language=language;
    this.setTitle(language.getLanguageInUse().getString("AboutDialog.title"));
    this.parent = parent;
    try {
        jbInit();
    } catch (Exception e) {
        e.printStackTrace();
    }
    pack();
}

その結果、次のようになります。

java.lang.NullPointerException at net.sf.jmoney.gui.AboutDialog.<init>(AboutDialog.java:67)

67行目は次のとおりです。

this.setTitle(language.getLanguageInUse().getString("AboutDialog.title"));

私たちのインターフェースは次のとおりです。

public interface Language {

    public ResourceBundle getLanguageInUse();
}

そしてポーランド語のクラスは次のとおりです。

public class Polish implements Language {

    private ResourceBundle languageInUse;

    public Polish() {
        languageInUse = ResourceBundle.getBundle(Constants.LANGUAGE_PL);
    }

    public ResourceBundle getLanguageInUse() {
        return languageInUse;
    }


}

迷っちゃった...

4

2 に答える 2

13

「フィールドインジェクション」を使用しています。これにより、注入された値をコンストラクターで使用することが難しくなります。Guiceがオブジェクトを作成する場合(現在は発生していません)、またはを使用する場合でもinjector.injectMembers(aboutDialog)、インジェクターが必要なフィールドを挿入する前にコンストラクターが実行されます。

さまざまなパラメーターと注入されたパラメーターを受け取るクラスを作成するのは少し難しいです。これにより、いくつかのオプションが残ります。

  • JFrameを挿入します。コンストラクターの作成時に使用するJFrameがわかっている場合はbind(JFrame.class).toInstance(myJFrame);、モジュールで使用してください。次に、GuiceはAboutDialogを完全に作成できます。

  • ファクトリを手動で作成します。そうすれば、注入AboutDialog.Factoryして電話をかけるだけで、createを取得できますAboutDialog。次のようになります。

    public class AboutDialog extends JDialog {
    
      /** Injectable factory. */
      public static class Factory {
        @Inject private Language language;
    
        public AboutDialog create(JFrame parent) {
          return new AboutDialog(parent, language);
        }
      }
    
      // no @Inject parameter; you're calling "new" yourself above!
      public AboutDialog(JFrame parent, Language language) {
        super(parent, "", true);
        this.language = language;
        // ... other initialization
      }
    }
    
  • ファクトリを作成し、Guiceにアシストインジェクションを介して接続させます。

    public class AboutDialog extends JDialog {
    
      public interface Factory {
        public AboutDialog create(JFrame parent);
      }
    
      // you need the @Inject, and also the @Assisted to tell Guice to
      // use the parameter instead of Guice bindings
      @Inject
      public AboutDialog(@Assisted JFrame parent, Language language) {
        super(parent, "", true);
        this.language = language;
        // ... other initialization
      }
    }
    
    public class StandardModule extends AbstractModule {
      @Override protected void configure() {
        bind(Language.class).to(Polish.class);
    
        // here every method in AboutDialog.Factory will be implemented
        // to create the method's return type [AboutDialog] based on
        // the parameters (like JFrame) and the bindings (like Language)
        install(new FactoryModuleBuilder().build(AboutDialog.Factory.class));
      }
    }
    

質問のコメントに記載されているように、AboutDialog(またはedコンストラクター/フィールドAboutDialog.Factoryを介して、またはそれ自体から)取得していることを確認してください。そうしないと、Guiceはパラメーターを挿入することを認識しません。@InjectInjector

于 2012-11-09T03:21:36.637 に答える
11

AboutDialog私はあなたがGuiceの助けを借りてあなたを作成していないと思います。

できることはinjector.injectMembers(this)、がどこにthisあるかを使用することですAboutDialog

最善の方法はAboutDialog、Guiceによって作成されるため、すべてのメンバーが注入されることです。

于 2012-11-08T21:46:05.617 に答える