Google Guiceのアレコレ ―Guice管理のクラスをプロバイダを使って取得順を制御する―

DIコンテナで管理しているクラスの取得順というのは、コンテナの責務ではないと思うけど、そういうのが必要な場面も稀にあります。

登録側

Providerメソッドに@Injectアノテーションをつけて、引数で必要なのを渡すだけ。
冗長だけど、まあシンプルです。

package jp.co.hogehoge.orderdwithprovider;

import java.util.ArrayList;
import java.util.List;

import jp.co.hogehoge.IService;
import jp.co.hogehoge.ServiceA;
import jp.co.hogehoge.ServiceB;

import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class SampleModule extends AbstractModule {
	public void configure() {
		bind(IService.class).annotatedWith(Names.named("A")).to(ServiceA.class);
		bind(IService.class).annotatedWith(Names.named("B")).to(ServiceB.class);
	}

	@Provides
	@Inject
	List<IService> proivdeIServiceList(@Named("A") IService serviceA,
			@Named("B") IService serviceB) {
		List<IService> list = new ArrayList<IService>();
		list.add(serviceA);
		list.add(serviceB);
		return list;
	}
}

実行側

これまで出てきた通りでとくに珍しいこともなく。
2回書いているのはちゃんと別インスタンスがとれているか確認したいから。

package jp.co.hogehoge.orderdwithprovider;

import java.util.List;

import jp.co.hogehoge.IService;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;

public class Run {
	public static void main(String[] args) {
		Injector injector = Guice.createInjector(new SampleModule());
		List<IService> list = injector.getInstance(Key
				.get(new TypeLiteral<List<IService>>() {
				}));
		for (IService iService : list) {
			System.out.println(iService);
			iService.print();
		}
		List<IService> list2 = injector.getInstance(Key
				.get(new TypeLiteral<List<IService>>() {
				}));
		for (IService iService : list2) {
			System.out.println(iService);
			iService.print();
		}
	}
}
実行結果

GuiceのデフォルトがPrototypeなので、ちゃんと別のインスタンスになってます。

jp.co.hogehoge.ServiceA@503429
my name is a
jp.co.hogehoge.ServiceB@1908ca1
my name is b
jp.co.hogehoge.ServiceA@100ab23
my name is a
jp.co.hogehoge.ServiceB@e3b895
my name is b