1 /** 2 * Copyright (C) 2015 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.inject.daggeradapter; 17 18 import com.google.common.base.Objects; 19 import com.google.inject.Binder; 20 import com.google.inject.Module; 21 import com.google.inject.internal.ProviderMethodsModule; 22 import com.google.inject.spi.ModuleAnnotatedMethodScanner; 23 24 import java.util.Arrays; 25 26 /** 27 * A utility to adapt classes annotated with {@link @dagger.Module} such that their 28 * {@link @dagger.Provides} methods can be properly invoked by Guice to perform their 29 * provision operations. 30 * 31 * <p>Simple example: <pre>{@code 32 * Guice.createInjector(...other modules..., DaggerAdapter.from(new SomeDaggerAdapter())); 33 * }</pre> 34 * 35 * <p>Some notes on usage and compatibility. 36 * <ul> 37 * <li>Dagger provider methods have a "SET_VALUES" provision mode not supported by Guice. 38 * <li>MapBindings are not yet implemented (pending). 39 * <li>Be careful about stateful modules. In contrast to Dagger (where components are 40 * expected to be recreated on-demand with new Module instances), Guice typically 41 * has a single injector with a long lifetime, so your module instance will be used 42 * throughout the lifetime of the entire app. 43 * <li>Dagger 1.x uses {@link @Singleton} for all scopes, including shorter-lived scopes 44 * like per-request or per-activity. Using modules written with Dagger 1.x usage 45 * in mind may result in mis-scoped objects. 46 * <li>Dagger 2.x supports custom scope annotations, but for use in Guice, a custom scope 47 * implementation must be registered in order to support the custom lifetime of that 48 * annotation. 49 * </ul> 50 * 51 * @author cgruber (at) google.com (Christian Gruber) 52 */ 53 public final class DaggerAdapter { 54 /** 55 * Returns a guice module from a dagger module. 56 * 57 * <p>Note: At present, it does not honor {@code @Module(includes=...)} directives. 58 */ 59 public static Module from(Object... daggerModuleObjects) { 60 // TODO(cgruber): Gather injects=, dedupe, factor out instances, instantiate the rest, and go. 61 return new DaggerCompatibilityModule(daggerModuleObjects); 62 } 63 64 /** 65 * A Module that adapts Dagger {@code @Module}-annotated types to contribute configuration 66 * to an {@link com.google.inject.Injector} using a dagger-specific 67 * {@link ModuleAnnotatedMethodScanner}. 68 */ 69 private static final class DaggerCompatibilityModule implements Module { 70 private final Object[] daggerModuleObjects; 71 72 private DaggerCompatibilityModule(Object... daggerModuleObjects) { 73 this.daggerModuleObjects = daggerModuleObjects; 74 } 75 76 @Override public void configure(Binder binder) { 77 for (Object module : daggerModuleObjects) { 78 binder.install(ProviderMethodsModule.forModule(module, DaggerMethodScanner.INSTANCE)); 79 } 80 } 81 82 @Override public String toString() { 83 return Objects.toStringHelper(this) 84 .add("modules", Arrays.asList(daggerModuleObjects)) 85 .toString(); 86 } 87 } 88 89 private DaggerAdapter() {} 90 } 91