Moduleの区分化 part2

先日書いた「Moduleの区分化」は、モジュール定義文 configure での exose() や install() を理解するサンプルとしてよいが、現実的でないので、
もう少し現実的に近い形式を書いてみた。

以下、Guice.createInjector の引数の形式は、Module...m あるいは、Iterable<Class extends Module> it であることから、createのパラメータを追加して
Module実装インスタンスのリストを外から与えても良いはず。

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.PrivateModule;
import com.google.inject.name.Names;

public final class PaperBuilder{
   private PaperBuilder(){}

   public static Paper create(PaperType type){

      Injector injector = Guice.createInjector(new AbstractModule(){
            // デフォルトのバインド定義
            @Override
            protected void configure(){
               binder().bind(String.class).annotatedWith(Names.named("AUTH")).toInstance("Sarah");
               bindConstant().annotatedWith(Names.named("SIZE")).to(240);
            }
         }
         , // Blue Paper の バインド定義
         new PrivateModule(){
            @Override
            protected void configure(){
               binder().bind(StencilPaper.class).annotatedWith(Blue.class).to(StencilPaper.class);
               expose(StencilPaper.class).annotatedWith(Blue.class);


               binder().bind(String.class).annotatedWith(Names.named("COLOR")).toInstance("BLUE");
               bindConstant().annotatedWith(Names.named("PRICE")).to(1200);
            }
         }
         , // Red Paper の バインド定義
         new PrivateModule(){
            @Override
            protected void configure(){
               binder().bind(StencilPaper.class).annotatedWith(Red.class).to(StencilPaper.class);
               expose(StencilPaper.class).annotatedWith(Red.class);


               binder().bind(String.class).annotatedWith(Names.named("COLOR")).toInstance("RED");
               bindConstant().annotatedWith(Names.named("PRICE")).to(1400);
            }
         }
         , // White Paper の バインド定義
         new PrivateModule(){
            @Override
            protected void configure(){
               binder().bind(StencilPaper.class).annotatedWith(White.class).to(StencilPaper.class);
               expose(StencilPaper.class).annotatedWith(White.class);


               binder().bind(String.class).annotatedWith(Names.named("COLOR")).toInstance("WHITE");
               bindConstant().annotatedWith(Names.named("PRICE")).to(1600);
            }
         }
      );
      return injector.getInstance(Key.get(StencilPaper.class,type.getTyp()));
   }
}
========================================================
public enum PaperType{
   BLUE(Blue.class)
   ,RED(Red.class)
   ,WHITE(White.class);
   //
   private Class<? extends java.lang.annotation.Annotation> cls;
   private PaperType(Class<? extends java.lang.annotation.Annotation> cls){
      this.cls = cls;
   }
   Class<? extends java.lang.annotation.Annotation> getTyp(){
      return this.cls;
   }

}
========================================================
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import com.google.inject.BindingAnnotation;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@BindingAnnotation
@interface Blue{
}

// Red , White も同様にアノテーションを用意
PrivateModule の選択をする為のアノテーション
Key.getの第2引数で指定する

========================================================
import com.google.inject.Inject;
import com.google.inject.name.Named;

class StencilPaper implements Paper{
   @Inject @Named("COLOR") private String color;
   @Inject @Named("AUTH")  private String author;
   @Inject @Named("SIZE")  private int sizeInt;
   @Inject @Named("PRICE") private Integer priceInt;

   @Override
   public String getColor(){
      return this.color;
   }
   @Override
   public int size(){
      return this.sizeInt;
   }
   @Override
   public String getAuthor(){
      return this.author;
   }
   @Override
   public int price(){
      return this.priceInt.intValue();
   }
}
========================================================
// 実行
      Paper bluePaper = PaperBuilder.create(PaperType.BLUE);

      System.out.println("■■■ BLUE  ■■■");
      System.out.println("color   = "+bluePaper.getColor());
      System.out.println("size    = "+bluePaper.size());
      System.out.println("author  = "+bluePaper.getAuthor());
      System.out.println("price   = "+bluePaper.price());

      Paper redPaper = PaperBuilder.create(PaperType.RED);

      System.out.println("■■■ RED   ■■■");
      System.out.println("color   = "+redPaper.getColor());
      System.out.println("size    = "+redPaper.size());
      System.out.println("author  = "+redPaper.getAuthor());
      System.out.println("price   = "+redPaper.price());

      Paper whitePaper = PaperBuilder.create(PaperType.WHITE);

      System.out.println("■■■ White ■■■");
      System.out.println("color   = "+whitePaper.getColor());
      System.out.println("size    = "+whitePaper.size());
      System.out.println("author  = "+whitePaper.getAuthor());
      System.out.println("price   = "+whitePaper.price()); ======================================
実行結果は、
■■■ BLUE ■■■
color = BLUE
size = 240
author = Sarah
price = 1200
■■■ RED ■■■
color = RED
size = 240
author = Sarah
price = 1400
■■■ White ■■■
color = WHITE
size = 240
author = Sarah
price = 1600