1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2014 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.producers; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import com.google.common.util.concurrent.ListenableFuture; 20*f585d8a3SJacky Wang import com.google.errorprone.annotations.CheckReturnValue; 21*f585d8a3SJacky Wang import dagger.internal.Beta; 22*f585d8a3SJacky Wang 23*f585d8a3SJacky Wang /** 24*f585d8a3SJacky Wang * An interface that represents the production of a type {@code T}. You can also inject 25*f585d8a3SJacky Wang * {@code Producer<T>} instead of {@code T}, which will delay the execution of any code that 26*f585d8a3SJacky Wang * produces the {@code T} until {@link #get} is called. 27*f585d8a3SJacky Wang * 28*f585d8a3SJacky Wang * <p>For example, you might inject {@code Producer} to lazily choose between several different 29*f585d8a3SJacky Wang * implementations of some type: <pre><code> 30*f585d8a3SJacky Wang * {@literal @Produces ListenableFuture<Heater>} getHeater( 31*f585d8a3SJacky Wang * HeaterFlag flag, 32*f585d8a3SJacky Wang * {@literal @Electric Producer<Heater>} electricHeater, 33*f585d8a3SJacky Wang * {@literal @Gas Producer<Heater>} gasHeater) { 34*f585d8a3SJacky Wang * return flag.useElectricHeater() ? electricHeater.get() : gasHeater.get(); 35*f585d8a3SJacky Wang * } 36*f585d8a3SJacky Wang * </code></pre> 37*f585d8a3SJacky Wang * 38*f585d8a3SJacky Wang * <p>Here is a complete example that demonstrates how calling {@code get()} will cause each 39*f585d8a3SJacky Wang * method to be executed: <pre><code> 40*f585d8a3SJacky Wang * 41*f585d8a3SJacky Wang * {@literal @}ProducerModule 42*f585d8a3SJacky Wang * final class MyModule { 43*f585d8a3SJacky Wang * {@literal @Produces ListenableFuture<A>} a() { 44*f585d8a3SJacky Wang * System.out.println("a"); 45*f585d8a3SJacky Wang * return Futures.immediateFuture(new A()); 46*f585d8a3SJacky Wang * } 47*f585d8a3SJacky Wang * 48*f585d8a3SJacky Wang * {@literal @Produces ListenableFuture<B>} b(A a) { 49*f585d8a3SJacky Wang * System.out.println("b"); 50*f585d8a3SJacky Wang * return Futures.immediateFuture(new B(a)); 51*f585d8a3SJacky Wang * } 52*f585d8a3SJacky Wang * 53*f585d8a3SJacky Wang * {@literal @Produces ListenableFuture<C>} c(B b) { 54*f585d8a3SJacky Wang * System.out.println("c"); 55*f585d8a3SJacky Wang * return Futures.immediateFuture(new C(b)); 56*f585d8a3SJacky Wang * } 57*f585d8a3SJacky Wang * 58*f585d8a3SJacky Wang * {@literal @Produces @Delayed ListenableFuture<C>} delayedC(A a, {@literal Producer<C>} c) { 59*f585d8a3SJacky Wang * System.out.println("delayed c"); 60*f585d8a3SJacky Wang * return c.get(); 61*f585d8a3SJacky Wang * } 62*f585d8a3SJacky Wang * } 63*f585d8a3SJacky Wang * 64*f585d8a3SJacky Wang * {@literal @}ProductionComponent(modules = MyModule.class) 65*f585d8a3SJacky Wang * interface MyComponent { 66*f585d8a3SJacky Wang * {@literal @Delayed ListenableFuture<C>} delayedC(); 67*f585d8a3SJacky Wang * } 68*f585d8a3SJacky Wang * </code></pre> 69*f585d8a3SJacky Wang * Suppose we instantiate the generated implementation of this component and call 70*f585d8a3SJacky Wang * {@code delayedC()}: <pre><code> 71*f585d8a3SJacky Wang * MyComponent component = DaggerMyComponent 72*f585d8a3SJacky Wang * .builder() 73*f585d8a3SJacky Wang * .executor(MoreExecutors.directExecutor()) 74*f585d8a3SJacky Wang * .build(); 75*f585d8a3SJacky Wang * System.out.println("Constructed component"); 76*f585d8a3SJacky Wang * {@literal ListenableFuture<C>} cFuture = component.delayedC(); 77*f585d8a3SJacky Wang * System.out.println("Retrieved future"); 78*f585d8a3SJacky Wang * C c = cFuture.get(); 79*f585d8a3SJacky Wang * System.out.println("Retrieved c"); 80*f585d8a3SJacky Wang * </code></pre> 81*f585d8a3SJacky Wang * Here, we're using {@code MoreExecutors.directExecutor} in order to illustrate how each call 82*f585d8a3SJacky Wang * directly causes code to execute. The above code will print: <pre><code> 83*f585d8a3SJacky Wang * Constructed component 84*f585d8a3SJacky Wang * a 85*f585d8a3SJacky Wang * delayed c 86*f585d8a3SJacky Wang * b 87*f585d8a3SJacky Wang * c 88*f585d8a3SJacky Wang * Retrieved future 89*f585d8a3SJacky Wang * Retrieved c 90*f585d8a3SJacky Wang * </code></pre> 91*f585d8a3SJacky Wang * 92*f585d8a3SJacky Wang * @since 2.0 93*f585d8a3SJacky Wang */ 94*f585d8a3SJacky Wang @Beta 95*f585d8a3SJacky Wang public interface Producer<T> { 96*f585d8a3SJacky Wang /** 97*f585d8a3SJacky Wang * Returns a future representing a running task that produces a value. Calling this method will 98*f585d8a3SJacky Wang * trigger the submission of this task to the executor, if it has not already been triggered. In 99*f585d8a3SJacky Wang * order to trigger this task's submission, the transitive dependencies required to produce the 100*f585d8a3SJacky Wang * {@code T} will be submitted to the executor, as their dependencies become available. 101*f585d8a3SJacky Wang * 102*f585d8a3SJacky Wang * <p>If the key is bound to a {@link Produces} method, then calling this method multiple times 103*f585d8a3SJacky Wang * will return the same future. 104*f585d8a3SJacky Wang */ 105*f585d8a3SJacky Wang @CheckReturnValue get()106*f585d8a3SJacky Wang ListenableFuture<T> get(); 107*f585d8a3SJacky Wang } 108