Guice:强制将绑定作为提供者注入

发布于 2024-11-27 10:07:38 字数 1067 浏览 0 评论 0原文

我正在寻找一种方法来强制某些 Guice 绑定仅作为提供者注入。例如,当有像这样的配置时,

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);
    }
}

我希望有办法配置我的模块,以便

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

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

可以很好地注入这样的类,但是像这样的实现

@Singleton
class ResultParser {
    private final ResultLogger resultLogger;

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

应该抛出一个 RuntimeException ,通知开发人员 ResultLogger 只能通过提供商获得。理想情况下,应尽快抛出异常,例如在构造注入器期间。我正在寻找一种简单的方法来使用 Guice 3.0 中现有的 API 来实现这一点。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蝶…霜飞 2024-12-04 10:07:38

也许您根本不应该实现 Provider,而只需要一个

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

@Singleton
class ResultParser {
   private final ResultLoggerProvider loggerProvider;

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

并删除其他绑定。

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.

赢得她心 2024-12-04 10:07:38

我认为这不是正确的方式。我想你需要smt之类的

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);

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);
意中人 2024-12-04 10:07:38

它应该可以绑定 Provider 而不是 ResultLogger。那是在你的模块中

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

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

bind(new TypeLiteral<Provider<ResultLogger>>(){}).to(ResultLoggerProvider.class);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文