2011-08-01 9 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; 
    } 
} 

は、ResultLoggerがプロバイダ経由でのみ利用可能であることを開発者に通知するRuntimeExceptionをスローする必要があります。例外はできるだけ早くスローされるのが理想的です。インジェクタの構成中に生じる。 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){}'。私はこれは合理的にきれいだと思うし、単体テストのときには大きな助けになります。どの設定値がクラスの振る舞いに影響を与えるのかがすぐに分かります。また、 'Configuration'オブジェクトを別に嘲笑することなく、単体テストの値を簡単に入れ替えることができます。 – ddso

-1

ResultLoggerではなくProviderをバインドする必要があります。それはあなたのモジュールにあります

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

それは動作しません。プロバイダにバインドすることはできません。 –

関連する問題