2011-08-01 68 views
2

我正在尋找一種強制某些Guice綁定僅作爲提供者注入的方法。例如,當有喜歡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來實現這一點。

回答

4

也許你不應該在所有實現提供商,只是有一個

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

@Singleton 
class ResultParser { 
    private final ResultLoggerProvider loggerProvider; 

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

和刪除其他綁定。

+0

這似乎是我的問題最合理的解決方案。我想通過嘗試使用Guice Provider類和API,我想「太過於」了。謝謝! – ddso

1

我認爲這是不對的。我想你需要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); 
+0

這是一個有趣的問題,謝謝。不幸的是,對我的情況來說,這並不實際,因爲我需要有這些提供者對象。我正在構建一個小框架來注入易於更改的配置值,所以我爲它們動態地構建提供者。 – ddso

+0

@dosendoc我認爲你應該做一些包裝,而不是強迫你的用戶使用「僞提供者」。 –

+0

目前,我的API允許我寫這樣的構造函數:'@Inject public DatabaseLogger(@ConfigValue(DatabaseOptions.HOST)Provider databaseHost){}'。我認爲這是相當乾淨的,它對單元測試有很大幫助,因爲它可以立即清楚哪些配置值會影響課程的行爲。它還允許您輕鬆地交換獨立測試的值,而無需單獨模擬一些「配置」對象。 – ddso

-1

它應該工作,而不是ResultLogger綁定提供程序。這是在你的模塊

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

這是行不通的。你不能綁定到提供者。 –