2

Guice 3.0でデフォルトのバインディングを宣言する方法はありますか?

これが私が期待したものの例です:

//Constructor for Class Impl1
@Inject
public Impl1 (@One IMyOwn own)
{
   ...
}

//Constructor for Class Impl2
@Inject
public Impl2 (@Two IMyOwn own)
{
   ...
}

//Declare a default binding
bind(IMyOwn.class).to(DefaultMyOwn.class);

//Then, if I want to bind a custom implementation for @Two
bind(IMyOwn.class).annotatedWith(Two.class).to(TwoMyOwn.class);

実際、すべてのアノテーション(@ One、@ Two)のバインディングを宣言する必要があるため、この例は機能しません。

Guiceでそれを行うための解決策はありますか?ありがとう。

4

3 に答える 3

2

@Named バインディングを使用します。

Github の Guice リファレンスから:

Guice には、文字列を使用する組み込みのバインディング アノテーション @Named が付属しています。

public class RealBillingService implements BillingService {
  @Inject
  public RealBillingService(@Named("Checkout") CreditCardProcessor processor) {
    ...
  }

特定の名前をバインドするには、Names.named() を使用してインスタンスを作成し、annotatedWith に渡します。

bind(CreditCardProcessor.class)
    .annotatedWith(Names.named("Checkout"))
    .to(CheckoutCreditCardProcessor.class);

だからあなたの場合、

//Constructor for Class Impl1
@Inject
public Impl1 (@Named("One") IMyOwn own)
{
   ...
}

//Constructor for Class Impl2
@Inject
public Impl2 (@Named("Two") IMyOwn own)
{
   ...
}

モジュールは次のようになります。

public class MyOwnModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(IMyOwn.class)
        .annotatedWith(Names.named("One"))
        .to(DefaultMyOwn.class);

    bind(IMyOwn.class)
        .annotatedWith(Names.named("Two"))
        .to(TwoMyOwn.class);
  }
}
于 2016-06-23T03:24:47.347 に答える
2

Guice 4.X にはOptional Binderがあります。

public class FrameworkModule extends AbstractModule {
  protected void configure() {
    OptionalBinder.newOptionalBinder(binder(), Renamer.class);
  }
}

public class FrameworkModule extends AbstractModule {
  protected void configure() {
    OptionalBinder.newOptionalBinder(
               binder(),
               Key.get(String.class, LookupUrl.class))
                  .setDefault().toInstance(DEFAULT_LOOKUP_URL);
  }
}

Guice 3.0 では、デフォルト コンストラクターの自動バインドを利用できる場合があります。

  1. 単一の @Inject または引数なしの public コンストラクターを使用します。

ただし、デフォルトのコンストラクターは同じ具象クラスである必要があるため、派生が面倒になる可能性があるため、これには制約があります。

于 2018-02-20T08:56:23.543 に答える
0

Guice は、構成 (別名バインディング) を可能な限りチェックしようとします。@Oneこれはまた、不足しているバインディングがエラーなのか、それともデフォルトのケースにマップすべきなのかを Guice が判断できないことを意味します。

詳細に興味がある場合は、Guice でBindingResolutionシーケンスを検索してください。ステップ 4 とステップ 6 はバインド アノテーションを処理し、ステップ 6 はデフォルトを明示的に禁止しているため、運が悪いと思います。

.6. 依存関係にバインディング アノテーションがある場合は、あきらめてください。Guice は、注釈付きの依存関係のデフォルトのバインディングを作成しません。

したがって、できる最善の方法は、@One次のようにデフォルトにマップするヒントを Guice に提供することです。

bind(IMyOwn.class).annotatedWith(One.class).to(IMyOwn.class);

DefaultMyOwnしたがって、具体的なデフォルト クラスを複数回指定する必要はありません。

于 2012-09-01T11:27:15.117 に答える