Google guice のインジェクションバインド定義で、
com.google.inject.TypeLiteral は、良くこのように使用される。
Injector injector = Guice.createInjector(new AbstractModule(){ @Override protected void configure(){ binder().bind(new TypeLiteral<List<String>>(){}) .toInstance(new ArrayList<String>()); } } );
(例題)
import java.util.function.Function; import com.google.inject.ImplementedBy; public interface SampleBuilder<R extends BaseDto>{ public R create(String str, Function<String, R> function); }
import java.util.function.Function; public class SampleBuilderImpl<R extends BaseDto> implements SampleBuilder<R> { @Override public R create(String str, Function<String, R > function){ return function.apply(str); } }
インジェクション対象は、このような状況とする
@Inject private SampleBuilder<SampleDto> builder;
こんな時、TypeLiteral を使わずに、
Injector injector = Guice.createInjector(new AbstractModule(){ @Override protected void configure(){ binder().bind(SampleBuilder.class).to(SampleBuilderImpl.class); } });
これはダメだ。
com.google.inject.ConfigurationException: Guice configuration errors
1) [Guice/MissingImplementation]: No implementation for SampleBuilder
と、怒られてしまう。
TypeLiteral を使うならこうする。
import com.google.inject.TypeLiteral; Injector injector = Guice.createInjector(new AbstractModule(){ @Override protected void configure(){ binder().bind(new TypeLiteral<SampleBuilder<SampleDto>>(){}).to(new TypeLiteral<SampleBuilderImpl<SampleDto>>(){}); } });
これで解決なのだが、TypeLiteral の bind定義を書かなくても
インターフェースの方で、@ImplementedBy で実装クラスを指定する方法でも解決する。
import com.google.inject.ImplementedBy; import java.util.function.Function; @ImplementedBy(SampleBuilderImpl.class) public interface SampleBuilder<R extends BaseDto>{ public R create(String str, Function<String, R> function); }
@ImplementedBy はとても便利