开发者

Guice: Forcing a binding to be injected as a provider

I'm looking for a way to force certain Guice bindings to be injected as providers only. For example, when there is a configuration like

interface ResultLogger {
    void log(String resultAsString);
}

class ResultLoggerProvider implements Provider<ResultLogger> {
    // ...
}

class ResultDisplayModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(ResultLogger.class).toProvider(ResultLoggerProvider.class);
    }
}

I would like to have way to configure my module so that a class like

@Singleton
class ResultParser {
    private final Provider<ResultLogger> loggerProvider;

    @Inject
    public ResultParser(Provider<ResultLogger> loggerProvider) {
        this.loggerProvider = loggerProvider;
    }
}

can be injected just fine, but an implementation like

@Singleton
class ResultParser {
    private final ResultLogger resultLogger;

    @Inject
    public ResultParser(ResultLogger resultLogger) {
        this.resultLogger = resultLogger;
    }
}

should throw a RuntimeException which notifies the developer that ResultLogger is only available via a provider. The exception would ideally be thrown as soon as possible, e.g. 开发者_高级运维during construction of the injector. I'm looking for an easy way to achieve this using the existing API in Guice 3.0.


Maybe you should not implement Provider at all and just have a

@Singleton
public class ResultLoggerProvider {
   public ResultLogger get() {...}
   // ...
}

@Singleton
class ResultParser {
   private final ResultLoggerProvider loggerProvider;

   @Inject
   public ResultParser(ResultLoggerProvider loggerProvider) {
      this.loggerProvider = loggerProvider;
   }
}

and remove the other bindings.


I think that it isn't right way. I guess you need smt like

interface ResultLogger {
    void log(String resultAsString);
}
class ResultLoggerWrapper implements ResultLogger {
      @Inject @Named("day") ResultLogger dayLogger;
      @Inject @Named("night") ResultLogger nightLogger;
      public void log(String resultAsString){
           if(isDay()) {
                 dayLogger.log(resultAsString)
           } else {
                 nightLogger.log(resultAsString)
           }
      }
}  

bind(ResultLogger.class).to(ResultLoggerWrapper.class);


It should work to bind Provider instead of ResultLogger. That is in your module

bind(new TypeLiteral<Provider<ResultLogger>>(){}).to(ResultLoggerProvider.class);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜