Guice:如何注入接口默认实现的实例?

Guice: How to Inject an instance of the default implementation of an interface?

我有一个既有默认实现又有客户端特定实现的接口。

接口:

@ImplementedBy(CoreServiceImpl.class)
interface CoreService {
  // Methods
}

默认实现:

class CoreServiceImpl implements CoreService {
  // Methods
}

在我的特定 Guice 模块中,我使用了不同的实现:

模块:

...
bind(CoreService.class).to(ClientSpecificServiceImpl.class);
...

实施:

class ClientSpecificServiceImpl implements CoreService {
  // Methods
}

但是,在此 class 中,我需要一个默认实现的实例。

如何告诉 Guice "inject an instance of the default implementation of this interface"?

我可以通过类型名称引用 current 默认实现,例如

class ClientSpecificServiceImpl implements CoreService {

  private final CoreServiceImpl coreServiceImpl;

  @Inject
  ClientSpecificServiceImpl(CoreServiceImpl coreServiceImpl) {
    this.coreServiceImpl = coreServiceImpl;
  }
}

.. 但如果默认实现(@ImplementedBy 中的实现)发生变化,我不会选择更改。这应该通过反思来完成吗?有没有更好的方法?

如果您希望在不同的地方注入不同的实现,请使用注入注释。换句话说,对于一个客户:

class ClientSpecificApp {
  private final CoreService coreService;

  @Inject
  ClientSpecificServiceImpl(@Named("clientName") CoreService coreService) {
    this.coreService = coreService;
  }
}

对于其他所有人:

class DefaultApp {
  private final CoreService coreService;

  @Inject
  DefaultApp(CoreService coreService) {
    this.coreService = coreService;
  }
}

然后,在您的 Guice 模块中绑定该注释:

protected void configure() {
    bind(CoreService.class).annotatedWith(Names.named("clientName") CoreService);
}

然后,如果客户端特定版本发生变化,您只需更改模块中的绑定即可。

进一步阅读:Binding Annotations