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 有可选的 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 或公共无参数构造函数。

但这有限制,因为您的默认构造函数需要属于相同的具体类,因此派生可能会变得很麻烦。

于 2018-02-20T08:56:23.543 回答
0

Guice 尝试尽可能多地检查您的配置(也称为绑定)。这也意味着,Guice 无法判断缺少的绑定@One是错误还是应该映射到某些默认情况。

如果您对细节感兴趣,请在 Guice 中查找BindingResolution序列。由于第 4 步和第 6 步处理绑定注释,而第 6 步明确禁止默认,我认为您不走运。

.6. 如果依赖有绑定注解,放弃。Guice 不会为带注释的依赖项创建默认绑定。

所以你能做的最好的就是为 Guice 提供一个提示,它@One应该像这样映射到默认值:

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

所以你不需要DefaultMyOwn多次声明具体的默认类。

于 2012-09-01T11:27:15.117 回答