レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

[翻訳]Guice User's Guide ■20. Custom Providers

カスタムプロバイダー

Sometimes you need to create your objects manually rather than let Guice create them. For example, you might not be able to add @Inject annotations to the implementation class as it came from a 3rd party. In these cases, you can implement a custom Provider. Guice can even inject your provider class. For example:

ときには、オブジェクトをGuiceに生成させるよりも手動で生成する必要があるときがあります。たとえば、サードパーティー制のクラスの実装であるために@Injcetアノテーションが使えないことがありえます。このような場合、カスタムプロバイダーを実装することができます。Guiceは、プロバイダークラスでさえもインジェクトすることができます。

class WidgetProvider implements Provider<Widget> {

  final Service service;

  @Inject
  WidgetProvider(Service service) {
    this.service = service;
  }

  public Widget get() {
    return new Widget(service);
  }
}

You bind Widget to WidgetProvider like so:
次のように、WidgetProviderをWidgetにバインドすることができます。

bind(Widget.class).toProvider(WidgetProvider.class);

Injecting the custom providers enables Guice to check the types and dependencies up front. Custom providers can reside in any scope independent of the scope of the objects they provide. By default, Guice creates a new provider instance for every injection. In the above example, if each Widget needs its own instance of Service, our code will work fine. You can specify a different scope for a custom factory using a scope annotation on the factory class or by creating a separate binding for the factory.

カスタムプロバイダーにインジェクトすることは、Guiceが事前に、型と依存性のチェックをすることを可能にします。カスタムプロバイダーは、それらが提供するオブジェクトのスコープから独立して、どのスコープにも存在することが出来ます。デフォルトでは、Guiceは、すべてのインジェクションに対して新しいプロバイダーインスタンスを作成します。上記のサンプルの中では、それぞれのWidgetが独自のServiceインターフェイスインスタンスを必要とする場合でも、このコードで十分に機能します。ファクトリークラスでスコープアノテーションを使うことで、カスタムファクトリー毎に異なるスコープを指定することが出来ます。または、ファクトリー毎に分離したバインディングを作る事によっても可能です。