2012-02-22 8 views
2

Javaで単純な依存性注入コンテナを作成したいと思います。私は次のように使用することができます何か:Javaでシンプルな依存性注入コンテナを作成し、オブジェクトを動的に作成する

DI.register(ITheInterface, ClassImplementingInterface); 
obj = DI.create(ITheInterface); 

がどのようにregister & createを実装する実際のコードは次のようになりますか?

public class Container { 

    protected static Container instance; 
    protected Hashtable<Class<?>, Class<?>> classMap; 

    protected Container() { 
     this.classMap = new Hashtable<Class<?>, Class<?>>(); 
    } 

    public static Container getInstance() { 
     if (Container.instance == null) 
      Container.instance = new Container(); 
     return Container.instance; 
    } 

    public void register(Class<?> forInterface, Class<?> toUse) { 
     this.classMap.put(forInterface, toUse); 
    } 

    public Object create(Class<?> forInterface) throws Exception { 
     if (!this.classMap.containsKey(forInterface)) 
      throw new Exception("Dependency Ingection Container does not have a class registered for use with " + forInterface.getName()); 
     return this.classMap.get(forInterface).newInstance(); 
    } 
} 

テストコード:

interface ITest { 
    public String getName(); 
    public void setName(String name); 
} 

class Test1 implements ITest { 

    protected String name; 

    @Override 
    public String getName() { 
     return this.name; 
    } 

    @Override 
    public void setName(String name) { 
     this.name = name; 
    } 

} 

public class Test { 
    public static void main(String[] args) throws Exception { 
     Container di = Container.getInstance(); 
     di.register(ITest.class, Test1.class); 
     ITest t1 = (ITest)di.create(ITest.class); 
     t1.setName("Yay!!!"); 
     System.out.println(t1.getName()); 
    } 
} 

UPDATE私は@Billによって提供されたリンクを理解しようとするのはなぜ

、私は私の試みでいただきました!間違って理解したいです

私が持っているエラー:

Exception in thread "main" java.lang.IllegalAccessException: Class dependencyinjection.Container can not access a member of class Test1 with modifiers "" 
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:95) 
    at java.lang.Class.newInstance0(Class.java:366) 
    at java.lang.Class.newInstance(Class.java:325) 
    at dependencyinjection.Container.create(Container.java:27) 
    at Test.main(Test.java:32) 

UPDATE 2

私はクラスpublicを作るとき、それは動作します考え出しました。別の問題があります。私はジェネリックインターフェイスに基づいてクラスを作成したいと思います。例えば。現在

  • IDataMapper<Event> ==>EventDataMapper
  • IDataMapper<Venue> ==>VenueDataMapper

、私がしなければ

di.register(IDataMapper<Event>.class, EventDataMapper.class); 

は私がIDataMapper取得し、Eventは、変数

に解決されていません

答えて

3

JSRの簡単な実装を確認できます。012 here

かなりわかりやすいです。編集内容を答えるために

Test1のは、コンテナが別のパッケージであるパッケージプライベートクラスは、Test1のコンストラクタへのアクセス権を持っていないです。あなたは、次の手順を実行して、この問題を回避することができます

Constructor c = this.classMap.get(forInterface).getDeclaredConstructor(); 
c.setAccessible(true); 
return c.newInstance(); 
+0

私はリンクの内容を理解し、なぜあなたは、メインの質問に私の更新では、この時の私の試みで私のミスを指摘することができれば、それは素晴らしいことだろう –

+0

ありがとうあなたの助けに。 'IDataMapper .class、...)' IDataMapperと 'Event'が変数に解決されないと言っていますが、これをどうやって解決できますか? DataMapperごとに1つのインターフェイスが必要ですか? –

+0

ジェネリックインターフェイスの登録はやや難しくなります。 IDataMapper は、タイプ消去のため、実行時には単純にIDataMapperです。 – Justin

関連する問題