package org.opensilk.common.core.mortar; import android.annotation.SuppressLint; import android.content.Context; import java.lang.reflect.Method; import mortar.MortarScope; import static java.lang.String.format; public class DaggerService { public static final String DAGGER_SERVICE = DaggerService.class.getName(); /** * Caller is required to know the type of the component for this context. */ @SuppressWarnings("unchecked") @SuppressLint("WrongConstant") public static <T> T getDaggerComponent(Context context) { //noinspection ResourceType return (T) context.getSystemService(DAGGER_SERVICE); } /** * Caller is required to know the type of the component for this scope. * * @throws IllegalArgumentException if there is no DaggerService attached to this scope * @return The Component associated with this scope */ @SuppressWarnings("unchecked") // public static <T> T getDaggerComponent(MortarScope scope) { if (scope.hasService(DaggerService.DAGGER_SERVICE)) { return (T) scope.getService(DaggerService.DAGGER_SERVICE); } throw new IllegalArgumentException(format("No dagger service found in scope %s", scope.getName())); } /** * Magic method that creates a component with its dependencies set, by reflection. Relies on * Dagger2 naming conventions. */ public static <T> T createComponent(Class<T> componentClass, Object... dependencies) { String fqn = componentClass.getName(); String packageName = componentClass.getPackage().getName(); // Accounts for inner classes, ie MyApplication$Component String simpleName = fqn.substring(packageName.length() + 1); String generatedName = (packageName + ".Dagger" + simpleName).replace('$', '_'); try { Class<?> generatedClass = Class.forName(generatedName); Object builder = generatedClass.getMethod("builder").invoke(null); for (Method method : builder.getClass().getDeclaredMethods()) { Class<?>[] params = method.getParameterTypes(); if (params.length == 1) { Class<?> dependencyClass = params[0]; for (Object dependency : dependencies) { if (dependencyClass.isAssignableFrom(dependency.getClass())) { method.invoke(builder, dependency); break; } } } } //noinspection unchecked return (T) builder.getClass().getMethod("build").invoke(builder); } catch (Exception e) { throw new RuntimeException(e); } } }