import com.google.inject.AbstractModule;
import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
public class AlivenessMonitorWiring extends AbstractModule {
@Override
protected void configure() {
- classPathBinder.bind(binder(), AlivenessMonitorService.class);
+ classPathBinder.bindAllSingletons("org.opendaylight.genius.alivenessmonitor", binder());
}
-
}
}
/**
- * Binds the given interfaces in the given binder, using implementations discovered by scanning the class path.
+ * 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 (modeled as a generic consumer)
+ */
+ public void bindAllSingletons(String prefix, BiConsumer<Class, Class> binder) {
+ implementations.forEach((interfaceName, singletonClass) -> {
+ if (singletonClass.getName().startsWith(prefix)) {
+ try {
+ Class interfaceClass = Class.forName(interfaceName);
+ binder.accept(interfaceClass, singletonClass);
+ // TODO later probably lower this info to debug, but for now it's very useful..
+ LOG.info("Bound {} to {}", interfaceClass, singletonClass);
+ } catch (ClassNotFoundException e) {
+ LOG.warn("ClassNotFoundException on Class.forName: {}", interfaceName, e);
+ }
+ }
+ });
+ // 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.
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) {
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));
+ }
}
import java.util.HashMap;
import java.util.Map;
-import org.junit.Before;
import org.junit.Test;
import org.opendaylight.infrautils.inject.ClassPathScanner;
public class ClassPathScannerTest {
- private final Map<Class<?>, Class<?>> bindings = new HashMap<>();
- @Before
- public void setup() {
- new ClassPathScanner("org.opendaylight.infrautils.inject.tests").bind(bindings::put,
- ClassPathScannerTestTopInterface.class);
+ 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 verifyImplementationBinding() {
+ public void testImplicitBinding() {
+ Map<Class<?>, Class<?>> bindings = new HashMap<>();
+ new ClassPathScanner(PREFIX).bindAllSingletons(PREFIX, bindings::put);
assertThat(bindings).containsExactly(
ClassPathScannerTestTopInterface.class, ClassPathScannerTestImplementation.class);
}