web-dev-qa-db-ja.com

Guice:@Namedを使用してオブジェクトを作成する

Guiceを使用して、

_@Inject @Named("light")
Color light;
_

使うことができます

_bind(Color.class).annotatedWith(Names.named("light"))
    .toInstance(new Color("white"));
_

colorコンストラクターが色名のみを必要とする場合にそれを白色にバインドします。

しかし、ColorコンストラクターがGuiceによって作成されたオブジェクトも必要とする場合、どうすればよいですか?例えば:

_@Inject
public Color(ColorSet colorset, String colorName) {...}
_

ここで、colorsetは実行時にGuiceによって作成され、configure(){...}では使用できません。

私はそれなしでやりたいです:

  • 注入する必要のある色ごとにクラス/サブクラスを作成する(WhiteColorなど)
  • コードで直接リフレクションを使用する
  • ColorFactoy factory; factory.get("light");の代わりに@Named("light") Color light;を使用するようにクラスを変更する
13
Ali Shakiba

これを行う最良の方法は、ファクトリではなく @Providesメソッド 。私の会社はGuiceを非常に広範囲に使用しており、requestInjectionは暗黙の依存関係の非常に壊れやすいグラフを簡単に設定できるため、常に悪い考えと見なされています。

これがどのように見えるべきかです:

public class FooModule extends AbstractModule {
  protected void configure() {
    // do configuration
  }

  @Provides
  @Named("white")
  Color provideWhiteColor(ColorSet colorSet) {
    return colorSet.white(); // or whatever
  }

  @Provides
  @Named("black")
  Color provideBlackColor(ColorSet colorSet) {
    return colorSet.black(); // or whatever
  }

  // etc
}
27

モジュール内にファクトリをセットアップし、そのファクトリにインジェクションを要求してColorSetに入力することができます。

モジュール:

ColorFactory colorFactory = new ColorFactory();

requestInjection(colorFactory);

bind(Color.class).annotatedWith(Names.named("light")).toInstance(colorFactory.buildColor("white"));
bind(Color.class).annotatedWith(Names.named("dark")).toInstance(colorFactory.buildColor("black"));

ColorFactory:

public class ColorFactory {

    private ColorSet colorSet;

    public Color buildColor(String color){
        return new Color(colorSet, color);
    }

    @Inject
    public void setColorSet(ColorSet colorSet) {
        this.colorSet = colorSet;
    }
}
2
John Ericksen