import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ScanResult;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
});
// we do not want nor have to scan the @Singleton's @Inject annotated constructor; will also auto-discover.
}
-
- /**
- * Binds the given interfaces, using implementations discovered by scanning the class path.
- *
- * @param binder The binder (modeled as a generic consumer).
- * @param interfaces The requested interfaces.
- */
- public <T> void bind(BiConsumer<Class<T>, Class<? extends T>> binder, Class... interfaces) {
- for (Class requestedInterface : interfaces) {
- bindImplementationFor(binder, requestedInterface);
- }
- // TODO Perhaps return interfaces which weren’t bound?
- }
-
- @SuppressWarnings("unchecked")
- private <T> void bindImplementationFor(BiConsumer<Class<T>, Class<? extends T>> binder, Class requestedInterface) {
- Class implementation = implementations.get(requestedInterface.getName());
- if (implementation != null) {
- binder.accept(requestedInterface, implementation);
- // TODO later probably lower this info to debug, but for now it's very useful..
- LOG.info("Bound {} to {}", requestedInterface, implementation);
- for (Constructor constructor : implementation.getDeclaredConstructors()) {
- Annotation injectAnnotation = constructor.getAnnotation(Inject.class);
- if (injectAnnotation != null) {
- for (Class parameterType : constructor.getParameterTypes()) {
- bindImplementationFor(binder, parameterType);
- }
- }
- }
- }
- }
}
package org.opendaylight.infrautils.inject.guice;
import com.google.inject.Binder;
+import javax.inject.Singleton;
import org.opendaylight.infrautils.inject.ClassPathScanner;
/**
}
/**
- * Binds the implementation of the given interface, if any, in the given binder, along with all dependencies.
+ * Binds all {@link Singleton} annotated classes discovered by scanning the class path to all their interfaces.
*
+ * @param prefix the package prefix of Singleton implementations to consider
* @param binder The binder to set up.
- * @param requestedInterface The requested interface.
*/
- public void bind(Binder binder, Class<?> requestedInterface) {
- scanner.bind((contract, implementation) -> binder.bind(contract).to(implementation), requestedInterface);
- }
-
public void bindAllSingletons(String prefix, Binder binder) {
scanner.bindAllSingletons(prefix, (contract, implementation) -> binder.bind(contract).to(implementation));
}
private static final String PREFIX = "org.opendaylight.infrautils.inject.tests";
- @Test
- public void testExplicitBinding() {
- Map<Class<?>, Class<?>> bindings = new HashMap<>();
- new ClassPathScanner(PREFIX).bind(bindings::put,
- ClassPathScannerTestTopInterface.class);
- assertThat(bindings).containsExactly(
- ClassPathScannerTestTopInterface.class, ClassPathScannerTestImplementation.class);
- }
-
@Test
public void testImplicitBinding() {
Map<Class<?>, Class<?>> bindings = new HashMap<>();