Author: aadamchik
Date: Sat Nov 21 15:56:33 2009
New Revision: 882933

URL: http://svn.apache.org/viewvc?rev=882933&view=rev
Log:
playing with DI ideas

* collection/map injection (aka 'contribution')
* some naming refactoring

Added:
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InterfaceBindingBuilder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ValueProvider.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java
    
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_ListConfiguration.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java
    
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapConfiguration.java
      - copied, changed from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
    
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorTest.java
Removed:
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InterfaceBindingBuilder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapInjector.java
    
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/spi/MapInjectorTest.java
Modified:
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java
    
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
    
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1.java
    
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1.java

Modified: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java 
(original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java 
Sat Nov 21 15:56:33 2009
@@ -26,4 +26,19 @@
      */
     <T> BindingBuilder<T> bind(Class<T> interfaceType);
 
+    /**
+     * Starts a binding of a map "configuration" that will be injected into an
+     * implementation class identified via the "implementationType" parameter.
+     * Configurations can only be injected via a constructor. Each type can 
take at most
+     * one configuration object via a constructor.
+     */
+    <T> MapBuilder<T> bindMap(Class<T> implementationType);
+
+    /**
+     * Starts a binding of a list "configuration" that will be injected into an
+     * implementation class identified via the "implementationType" parameter.
+     * Configurations can only be injected via a constructor. Each type can 
take at most
+     * one configuration object via a constructor.
+     */
+    <T> ListBuilder<T> bindList(Class<T> implementationType);
 }

Modified: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java 
(original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java 
Sat Nov 21 15:56:33 2009
@@ -18,7 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
-import org.apache.cayenne.di.spi.MapInjector;
+import org.apache.cayenne.di.spi.DefaultInjector;
 
 /**
  * A class that bootstraps the Cayenne DI registry.
@@ -26,6 +26,6 @@
 public class DIBootstrap {
 
        public static Injector createInjector(Module... modules) throws 
DIException {
-               return new MapInjector(modules);
+               return new DefaultInjector(modules);
        }
 }

Modified: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java 
(original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java 
Sat Nov 21 15:56:33 2009
@@ -18,7 +18,18 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+import java.util.List;
+import java.util.Map;
+
 public interface Injector {
 
-       <T> T getInstance(Class<T> type) throws DIException;
+    /**
+     * Returns a service instance bound in the container for a specific type. 
Throws
+     * {...@link DIException} if the type is not bound, or an instance can not 
be created.
+     */
+    <T> T getInstance(Class<T> type) throws DIException;
+
+    <T> Map<String, ?> getMapConfiguration(Class<T> type);
+
+    <T> List<?> getListConfiguration(Class<T> type);
 }

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java 
(from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java 
Sat Nov 21 15:56:33 2009
@@ -18,11 +18,14 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
-public class SimpleBinder implements Binder {
+/**
+ * A binding builder for list configurations.
+ * 
+ * @param <T> A type of the service for which the configuration is created.
+ */
+public interface ListBuilder<T> {
 
-       public <T> BindingBuilder<T> bind(Class<T> type) {
-               // TODO Auto-generated method stub
-               return null;
-       }
+    <E> ListBuilder<T> add(Class<? extends E> valueType) throws DIException;
 
+    <E> ListBuilder<T> add(E value) throws DIException;
 }

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java 
(from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java 
(original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java 
Sat Nov 21 15:56:33 2009
@@ -18,14 +18,14 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
-import org.apache.cayenne.di.spi.MapInjector;
-
 /**
- * A class that bootstraps the Cayenne DI registry.
+ * A binding builder for map configurations.
+ * 
+ * @param <T> A type of the service for which the configuration is created.
  */
-public class DIBootstrap {
+public interface MapBuilder<T> {
+
+    <E> MapBuilder<T> put(String key, Class<? extends E> valueType) throws 
DIException;
 
-       public static Injector createInjector(Module... modules) throws 
DIException {
-               return new MapInjector(modules);
-       }
+    <E> MapBuilder<T> put(String key, E value) throws DIException;
 }

Modified: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java
 Sat Nov 21 15:56:33 2009
@@ -20,6 +20,8 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Inject;
@@ -101,7 +103,24 @@
         Object[] args = new Object[constructorParameters.length];
 
         for (int i = 0; i < constructorParameters.length; i++) {
-            args[i] = injector.getInstance(constructorParameters[i]);
+
+            Class<?> parameter = constructorParameters[i];
+
+            // parameter must be declared as "java.util.Map". Use of specific 
map
+            // implementations in the declaration will make the injection much 
more
+            // complicated
+            if (Map.class.equals(parameter)) {
+                args[i] = 
injector.getMapConfiguration(constructor.getDeclaringClass());
+            }
+            // parameter must be declared as "java.util.List". Use of specific 
list
+            // implementations in the declaration will make the injection much 
more
+            // complicated
+            else if (List.class.equals(parameter)) {
+                args[i] = 
injector.getListConfiguration(constructor.getDeclaringClass());
+            }
+            else {
+                args[i] = injector.getInstance(parameter);
+            }
         }
 
         try {

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java
 Sat Nov 21 15:56:33 2009
@@ -20,17 +20,27 @@
 
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.BindingBuilder;
+import org.apache.cayenne.di.ListBuilder;
+import org.apache.cayenne.di.MapBuilder;
 
-class MapBinder implements Binder {
+class DefaultBinder implements Binder {
 
-    private MapInjector injector;
+    private DefaultInjector injector;
 
-    MapBinder(MapInjector injector) {
+    DefaultBinder(DefaultInjector injector) {
         this.injector = injector;
     }
 
     public <T> BindingBuilder<T> bind(Class<T> type) {
-        return new InterfaceBindingBuilder<T>(type, injector);
+        return new DefaultBindingBuilder<T>(type, injector);
+    }
+
+    public <T> ListBuilder<T> bindList(Class<T> implementationType) {
+        return new DefaultListBuilder<T>(implementationType, injector);
+    }
+
+    public <T> MapBuilder<T> bindMap(Class<T> implementationType) {
+        return new DefaultMapBuilder<T>(implementationType, injector);
     }
 
 }

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InterfaceBindingBuilder.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InterfaceBindingBuilder.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InterfaceBindingBuilder.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java
 Sat Nov 21 15:56:33 2009
@@ -22,12 +22,12 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
-class InterfaceBindingBuilder<T> implements BindingBuilder<T> {
+class DefaultBindingBuilder<T> implements BindingBuilder<T> {
 
     private Class<T> interfaceType;
-    private MapInjector injector;
+    private DefaultInjector injector;
 
-    InterfaceBindingBuilder(Class<T> interfaceType, MapInjector injector) {
+    DefaultBindingBuilder(Class<T> interfaceType, DefaultInjector injector) {
         this.interfaceType = interfaceType;
         this.injector = injector;
     }

Added: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java?rev=882933&view=auto
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java
 (added)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java
 Sat Nov 21 15:56:33 2009
@@ -0,0 +1,113 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.di.spi;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cayenne.di.DIException;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.Provider;
+
+public class DefaultInjector implements Injector {
+
+    private Map<String, Provider<?>> bindings;
+    private Map<String, MapProvider> mapConfigurations;
+    private Map<String, ListProvider> listConfigurations;
+
+    public DefaultInjector(Module... modules) throws DIException {
+
+        this.bindings = new HashMap<String, Provider<?>>();
+        this.mapConfigurations = new HashMap<String, MapProvider>();
+        this.listConfigurations = new HashMap<String, ListProvider>();
+
+        if (modules != null && modules.length > 0) {
+            DefaultBinder binder = new DefaultBinder(this);
+            for (Module module : modules) {
+                module.configure(binder);
+            }
+        }
+    }
+
+    Map<String, Provider<?>> getBindings() {
+        return bindings;
+    }
+
+    Map<String, MapProvider> getMapConfigurations() {
+        return mapConfigurations;
+    }
+
+    Map<String, ListProvider> getListConfigurations() {
+        return listConfigurations;
+    }
+
+    public <T> T getInstance(Class<T> type) throws DIException {
+        if (type == null) {
+            throw new NullPointerException("Null type");
+        }
+
+        String key = KeyGenerator.toKey(type);
+        Provider<T> provider = (Provider<T>) bindings.get(key);
+
+        if (provider == null) {
+
+            throw new DIException("Type is not bound in the  registry: " + 
type.getName());
+        }
+
+        return provider.get();
+    }
+
+    public <T> List<?> getListConfiguration(Class<T> type) {
+        if (type == null) {
+            throw new NullPointerException("Null type");
+        }
+
+        String key = KeyGenerator.toKey(type);
+        ListProvider provider = listConfigurations.get(key);
+
+        if (provider == null) {
+
+            throw new DIException(
+                    "Type has no bound list configuration in the registry: "
+                            + type.getName());
+        }
+
+        return provider.get();
+    }
+
+    public <T> Map<String, ?> getMapConfiguration(Class<T> type) {
+        if (type == null) {
+            throw new NullPointerException("Null type");
+        }
+
+        String key = KeyGenerator.toKey(type);
+        MapProvider provider = mapConfigurations.get(key);
+
+        if (provider == null) {
+
+            throw new DIException("Type has no bound map configuration in the 
registry: "
+                    + type.getName());
+        }
+
+        return provider.get();
+    }
+
+}

Added: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java?rev=882933&view=auto
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
 (added)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
 Sat Nov 21 15:56:33 2009
@@ -0,0 +1,69 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.di.spi;
+
+import org.apache.cayenne.di.DIException;
+import org.apache.cayenne.di.ListBuilder;
+
+class DefaultListBuilder<T> implements ListBuilder<T> {
+
+    private DefaultInjector injector;
+    private String implementationTypeKey;
+
+    DefaultListBuilder(Class<T> implementationType, DefaultInjector injector) {
+        this.injector = injector;
+        implementationTypeKey = KeyGenerator.toKey(implementationType);
+    }
+
+    public <E> ListBuilder<T> add(Class<? extends E> valueType) throws 
DIException {
+
+        // creating a provider chain for lazy resolution of singletons...
+        ConstructorProvider<E> provider0 = new 
ConstructorProvider<E>(valueType, injector);
+        FieldInjectingProvider<E> provider1 = new FieldInjectingProvider<E>(
+                provider0,
+                injector);
+        SingletonProvider<E> provider2 = new SingletonProvider<E>(provider1);
+
+        ListProvider listProvider = injector.getListConfigurations().get(
+                implementationTypeKey);
+        if (listProvider == null) {
+            listProvider = new ListProvider();
+            injector.getListConfigurations().put(implementationTypeKey, 
listProvider);
+        }
+
+        listProvider.add(provider2);
+        return this;
+    }
+
+    public <E> ListBuilder<T> add(E value) throws DIException {
+
+        ValueProvider<E> provider = new ValueProvider<E>(value);
+
+        ListProvider listProvider = injector.getListConfigurations().get(
+                implementationTypeKey);
+        if (listProvider == null) {
+            listProvider = new ListProvider();
+            injector.getListConfigurations().put(implementationTypeKey, 
listProvider);
+        }
+
+        listProvider.add(provider);
+        return this;
+    }
+
+}

Added: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java?rev=882933&view=auto
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
 (added)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
 Sat Nov 21 15:56:33 2009
@@ -0,0 +1,71 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.di.spi;
+
+import org.apache.cayenne.di.DIException;
+import org.apache.cayenne.di.MapBuilder;
+
+class DefaultMapBuilder<T> implements MapBuilder<T> {
+
+    private DefaultInjector injector;
+    private String implementationTypeKey;
+
+    DefaultMapBuilder(Class<T> implementationType, DefaultInjector injector) {
+        this.injector = injector;
+        implementationTypeKey = KeyGenerator.toKey(implementationType);
+    }
+
+    public <E> MapBuilder<T> put(String key, Class<? extends E> valueType)
+            throws DIException {
+
+        // creating a provider chain for lazy resolution of singletons...
+        ConstructorProvider<E> provider0 = new 
ConstructorProvider<E>(valueType, injector);
+        FieldInjectingProvider<E> provider1 = new FieldInjectingProvider<E>(
+                provider0,
+                injector);
+        SingletonProvider<E> provider2 = new SingletonProvider<E>(provider1);
+
+        MapProvider mapProvider = injector.getMapConfigurations().get(
+                implementationTypeKey);
+        if (mapProvider == null) {
+            mapProvider = new MapProvider();
+            injector.getMapConfigurations().put(implementationTypeKey, 
mapProvider);
+        }
+
+        // TODO: andrus 11/15/2009 - report overriding the key??
+        mapProvider.put(key, provider2);
+        return this;
+    }
+
+    public <E> MapBuilder<T> put(String key, E value) throws DIException {
+
+        ValueProvider<E> provider = new ValueProvider<E>(value);
+
+        MapProvider mapProvider = injector.getMapConfigurations().get(
+                implementationTypeKey);
+        if (mapProvider == null) {
+            mapProvider = new MapProvider();
+            injector.getMapConfigurations().put(implementationTypeKey, 
mapProvider);
+        }
+
+        // TODO: andrus 11/15/2009 - report overriding the key??
+        mapProvider.put(key, provider);
+        return this;
+    }
+}

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java
 Sat Nov 21 15:56:33 2009
@@ -18,31 +18,32 @@
  ****************************************************************/
 package org.apache.cayenne.di.spi;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
-public class SingletonProvider<T> implements Provider<T> {
+class ListProvider implements Provider<List<?>> {
 
-    private Provider<T> delegate;
-    private T instance;
+    private List<Provider<?>> providers;
 
-    public SingletonProvider(Provider<T> delegate) {
-        this.delegate = delegate;
+    public ListProvider() {
+        this.providers = new ArrayList<Provider<?>>();
     }
 
-    public T get() {
+    public List<?> get() throws DIException {
+        List<Object> list = new ArrayList<Object>(providers.size());
 
-        // using double-checked locking for lazy initialization, which is not 
guaranteed
-        // to work on all architectures and JVMs. Better alternatives? 
Synchronizing the
-        // entire method?
-        if (instance == null) {
-            synchronized (this) {
-                if (instance == null) {
-                    instance = delegate.get();
-                }
-            }
+        for (Provider<?> provider : providers) {
+            list.add(provider.get());
         }
 
-        return instance;
+        return list;
+    }
+
+    void add(Provider<?> provider) {
+        providers.add(provider);
     }
 
 }

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java
 Sat Nov 21 15:56:33 2009
@@ -18,31 +18,32 @@
  ****************************************************************/
 package org.apache.cayenne.di.spi;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
-public class SingletonProvider<T> implements Provider<T> {
+class MapProvider implements Provider<Map<String, ?>> {
 
-    private Provider<T> delegate;
-    private T instance;
+    private Map<String, Provider<?>> providers;
 
-    public SingletonProvider(Provider<T> delegate) {
-        this.delegate = delegate;
+    public MapProvider() {
+        this.providers = new HashMap<String, Provider<?>>();
     }
 
-    public T get() {
+    public Map<String, ?> get() throws DIException {
+        Map<String, Object> map = new HashMap<String, Object>();
 
-        // using double-checked locking for lazy initialization, which is not 
guaranteed
-        // to work on all architectures and JVMs. Better alternatives? 
Synchronizing the
-        // entire method?
-        if (instance == null) {
-            synchronized (this) {
-                if (instance == null) {
-                    instance = delegate.get();
-                }
-            }
+        for (Entry<String, Provider<?>> entry : providers.entrySet()) {
+            map.put(entry.getKey(), entry.getValue().get());
         }
 
-        return instance;
+        return map;
     }
 
+    void put(String key, Provider<?> provider) {
+        providers.put(key, provider);
+    }
 }

Modified: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java
 Sat Nov 21 15:56:33 2009
@@ -21,7 +21,7 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
-public class ProviderConstructorProvider<T> implements Provider<T> {
+class ProviderConstructorProvider<T> implements Provider<T> {
 
     private Class<? extends Provider<? extends T>> providerType;
 
@@ -45,7 +45,7 @@
             throw new DIException("Provider returned null object, provider 
type: "
                     + providerType.getName());
         }
-        
+
         return object;
     }
 }

Modified: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
 Sat Nov 21 15:56:33 2009
@@ -20,7 +20,7 @@
 
 import org.apache.cayenne.di.Provider;
 
-public class SingletonProvider<T> implements Provider<T> {
+class SingletonProvider<T> implements Provider<T> {
 
     private Provider<T> delegate;
     private T instance;

Copied: 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ValueProvider.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ValueProvider.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ValueProvider.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SimpleBinder.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ValueProvider.java
 Sat Nov 21 15:56:33 2009
@@ -16,13 +16,20 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.di;
+package org.apache.cayenne.di.spi;
 
-public class SimpleBinder implements Binder {
+import org.apache.cayenne.di.DIException;
+import org.apache.cayenne.di.Provider;
 
-       public <T> BindingBuilder<T> bind(Class<T> type) {
-               // TODO Auto-generated method stub
-               return null;
-       }
+class ValueProvider<T> implements Provider<T> {
 
+    private T value;
+
+    ValueProvider(T value) {
+        this.value = value;
+    }
+
+    public T get() throws DIException {
+        return value;
+    }
 }

Modified: 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1.java
 Sat Nov 21 15:56:33 2009
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.di.mock;
 
 public class MockImplementation1 implements MockInterface1 {

Copied: 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_ListConfiguration.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_ListConfiguration.java?p2=cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_ListConfiguration.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapBinder.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_ListConfiguration.java
 Sat Nov 21 15:56:33 2009
@@ -16,21 +16,29 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.di.spi;
+package org.apache.cayenne.di.mock;
 
-import org.apache.cayenne.di.Binder;
-import org.apache.cayenne.di.BindingBuilder;
+import java.util.List;
 
-class MapBinder implements Binder {
+import org.apache.cayenne.di.Inject;
 
-    private MapInjector injector;
+public class MockImplementation1_ListConfiguration implements MockInterface1 {
 
-    MapBinder(MapInjector injector) {
-        this.injector = injector;
+    private List<Object> configuration;
+
+    public MockImplementation1_ListConfiguration(@Inject List<Object> 
configuration) {
+        this.configuration = configuration;
     }
 
-    public <T> BindingBuilder<T> bind(Class<T> type) {
-        return new InterfaceBindingBuilder<T>(type, injector);
+    public String getName() {
+
+        StringBuilder buffer = new StringBuilder();
+
+        for (Object value : configuration) {
+            buffer.append(";").append(value);
+        }
+
+        return buffer.toString();
     }
 
 }

Copied: 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapConfiguration.java
 (from r882303, 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java)
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapConfiguration.java?p2=cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapConfiguration.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java&r1=882303&r2=882933&rev=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/SingletonProvider.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapConfiguration.java
 Sat Nov 21 15:56:33 2009
@@ -16,33 +16,34 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.di.spi;
+package org.apache.cayenne.di.mock;
 
-import org.apache.cayenne.di.Provider;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 
-public class SingletonProvider<T> implements Provider<T> {
+import org.apache.cayenne.di.Inject;
 
-    private Provider<T> delegate;
-    private T instance;
+public class MockImplementation1_MapConfiguration implements MockInterface1 {
 
-    public SingletonProvider(Provider<T> delegate) {
-        this.delegate = delegate;
+    private Map<String, Object> configuration;
+
+    public MockImplementation1_MapConfiguration(@Inject Map<String, Object> 
configuration) {
+        this.configuration = configuration;
     }
 
-    public T get() {
+    public String getName() {
+
+        StringBuilder buffer = new StringBuilder();
 
-        // using double-checked locking for lazy initialization, which is not 
guaranteed
-        // to work on all architectures and JVMs. Better alternatives? 
Synchronizing the
-        // entire method?
-        if (instance == null) {
-            synchronized (this) {
-                if (instance == null) {
-                    instance = delegate.get();
-                }
-            }
+        List<String> keys = new ArrayList<String>(configuration.keySet());
+        Collections.sort(keys);
+
+        for (String key : keys) {
+            
buffer.append(";").append(key).append("=").append(configuration.get(key));
         }
 
-        return instance;
+        return buffer.toString();
     }
-
 }

Modified: 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1.java?rev=882933&r1=882932&r2=882933&view=diff
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1.java
 (original)
+++ 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1.java
 Sat Nov 21 15:56:33 2009
@@ -1,3 +1,21 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
 package org.apache.cayenne.di.mock;
 
 public interface MockInterface1 {

Added: 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorTest.java
URL: 
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorTest.java?rev=882933&view=auto
==============================================================================
--- 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorTest.java
 (added)
+++ 
cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorTest.java
 Sat Nov 21 15:56:33 2009
@@ -0,0 +1,225 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.di.spi;
+
+import junit.framework.TestCase;
+
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.mock.MockImplementation1;
+import org.apache.cayenne.di.mock.MockImplementation1Alt;
+import org.apache.cayenne.di.mock.MockImplementation1_ListConfiguration;
+import org.apache.cayenne.di.mock.MockImplementation1_MapConfiguration;
+import org.apache.cayenne.di.mock.MockImplementation2;
+import org.apache.cayenne.di.mock.MockImplementation2Sub1;
+import org.apache.cayenne.di.mock.MockImplementation3;
+import org.apache.cayenne.di.mock.MockImplementation4;
+import org.apache.cayenne.di.mock.MockInterface1;
+import org.apache.cayenne.di.mock.MockInterface1Provider;
+import org.apache.cayenne.di.mock.MockInterface2;
+import org.apache.cayenne.di.mock.MockInterface3;
+import org.apache.cayenne.di.mock.MockInterface4;
+
+public class DefaultInjectorTest extends TestCase {
+
+    public void testConstructor_Empty() {
+        new DefaultInjector();
+        // no exceptions...
+    }
+
+    public void testConstructor_SingleModule() {
+        final boolean[] configureCalled = new boolean[1];
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                configureCalled[0] = true;
+            }
+        };
+
+        new DefaultInjector(module);
+        assertTrue(configureCalled[0]);
+    }
+
+    public void testConstructor_MultiModule() {
+
+        final boolean[] configureCalled = new boolean[2];
+
+        Module module1 = new Module() {
+
+            public void configure(Binder binder) {
+                configureCalled[0] = true;
+            }
+        };
+
+        Module module2 = new Module() {
+
+            public void configure(Binder binder) {
+                configureCalled[1] = true;
+            }
+        };
+
+        new DefaultInjector(module1, module2);
+        assertTrue(configureCalled[0]);
+        assertTrue(configureCalled[1]);
+    }
+
+    public void testClassBinding() {
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("MyName", service.getName());
+    }
+
+    public void testFieldInjection() {
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                
binder.bind(MockInterface2.class).to(MockImplementation2.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface2 service = injector.getInstance(MockInterface2.class);
+        assertNotNull(service);
+        assertEquals("altered_MyName", service.getAlteredName());
+    }
+
+    public void testFieldInjectionSuperclass() {
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                
binder.bind(MockInterface2.class).to(MockImplementation2Sub1.class);
+                
binder.bind(MockInterface3.class).to(MockImplementation3.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface2 service = injector.getInstance(MockInterface2.class);
+        assertNotNull(service);
+        assertEquals("altered_MyName:XName", service.getAlteredName());
+    }
+
+    public void testConstructorInjection() {
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                
binder.bind(MockInterface4.class).to(MockImplementation4.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface4 service = injector.getInstance(MockInterface4.class);
+        assertNotNull(service);
+        assertEquals("constructor_MyName", service.getName());
+    }
+
+    public void testProviderBinding() {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder
+                        .bind(MockInterface1.class)
+                        .toProvider(MockInterface1Provider.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("MyName", service.getName());
+    }
+
+    public void testClassReBinding() {
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1Alt.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("alt", service.getName());
+    }
+
+    public void testMapInjection() {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(
+                        MockImplementation1_MapConfiguration.class);
+
+                binder.bindMap(MockImplementation1_MapConfiguration.class).put(
+                        "x",
+                        "xvalue").put("y", "yvalue").put("x", "xvalue1");
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals(";x=xvalue1;y=yvalue", service.getName());
+    }
+
+    public void testListInjection() {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(
+                        MockImplementation1_ListConfiguration.class);
+
+                binder
+                        .bindList(MockImplementation1_ListConfiguration.class)
+                        .add("xvalue")
+                        .add("yvalue");
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals(";xvalue;yvalue", service.getName());
+    }
+}


Reply via email to