View Javadoc

1   /*
2    * Grapht, an open source dependency injector.
3    * Copyright 2014-2015 various contributors (see CONTRIBUTORS.txt)
4    * Copyright 2010-2014 Regents of the University of Minnesota
5    *
6    * This program is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU Lesser General Public License as
8    * published by the Free Software Foundation; either version 2.1 of the
9    * License, or (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14   * details.
15   *
16   * You should have received a copy of the GNU General Public License along with
17   * this program; if not, write to the Free Software Foundation, Inc., 51
18   * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19   */
20  package org.grouplens.grapht;
21  
22  import org.grouplens.grapht.solver.BindRule;
23  import org.grouplens.grapht.reflect.Satisfaction;
24  
25  import javax.annotation.Nonnull;
26  import javax.annotation.Nullable;
27  import javax.inject.Provider;
28  import javax.inject.Qualifier;
29  import java.lang.annotation.Annotation;
30  
31  /**
32   * Binding is part of the fluent API used for configuring an {@link Injector}.
33   * It represents a binding action from one type to another type.
34   * 
35   * @author <a href="http://grouplens.org">GroupLens Research</a>
36   * @param <T> The source type
37   */
38  public interface Binding<T> {
39      /**
40       * <p>
41       * Configure the binding to match the given {@link Qualifier} annotation.
42       * The given annotation type must be annotated with {@link Qualifier}. The
43       * created binding will match injection points only if the qualifier is
44       * applied to the injection point, unless the annotation inherits from the
45       * default qualifier.
46       * <p>
47       * This will override any previous name or qualifier annotation.
48       * 
49       * @param qualifier The Qualifier that must match
50       * @return A newly configured Binding
51       */
52      Binding<T> withQualifier(@Nonnull Class<? extends Annotation> qualifier);
53  
54      /**
55       * Configure the binding to match injection points that have been annotated with the exact
56       * annotation instance.
57       *
58       * <p>This will override any previous name or qualifier annotation.
59       *
60       * <p>The annotation provided must be serializable.  Annotations built by {@link
61       * org.grouplens.grapht.annotation.AnnotationBuilder} (recommended) or retrieved from the Java
62       * reflection API are serializable; if you use some other annotation implementation, it must be
63       * serializable.
64       *
65       * @param annot The annotation instance to match.
66       * @return A newly configured Binding
67       */
68      Binding<T> withQualifier(@Nonnull Annotation annot);
69  
70      /**
71       * Configure the binding to match injection points that have any qualifier annotation (including
72       * no qualifier).
73       *
74       * <p>This will override any previous name or qualifier annotation.
75       *
76       * @return A newly configured Binding
77       */
78      Binding<T> withAnyQualifier();
79  
80      /**
81       * <p>
82       * Configure the binding to only match injection points that have no
83       * qualifier. By default, the binding matches any injection point with the
84       * given type, whether or not its been qualified. A qualified binding to the
85       * same type will still be preferred first when resolving a qualified
86       * injection point.
87       * 
88       * @return A newly configured binding
89       */
90      Binding<T> unqualified();
91  
92      /**
93       * Exclude the provided type from being matched when examining injection
94       * points. Bindings can generate multiple {@link BindRule BindRules} for
95       * super and sub types. Excluded classes for a binding will not have
96       * BindRules generated for them.
97       * 
98       * @param exclude The type to exclude from automated rule generation
99       * @return A newly configured Binding
100      */
101     Binding<T> exclude(@Nonnull Class<?> exclude);
102     
103     /**
104      * Configure the binding so that a shared instance is always used when
105      * satisfying matched injection points, effectively making it a singleton or
106      * memoized within its container.
107      * 
108      * @return A newly configured Binding
109      */
110     Binding<T> shared();
111     
112     /**
113      * Configure the binding so that new instances are always created when
114      * satisfying matched injection.
115      * 
116      * @return A newly configured binding
117      */
118     Binding<T> unshared();
119 
120     /**
121      * Configure the binding so that its results are 'fixed'.  Fixed results will not be rewritten
122      * by the dependency solver in rewrite mode.
123      * @return A newly configured binding.
124      */
125     Binding<T> fixed();
126 
127     /**
128      * <p>
129      * Complete this binding by specifying a subtype that will satisfy the
130      * desired type. The implementation does not have to be instantiable; if
131      * it's not then additional bindings must be configured to bind to reach an
132      * instantiable type. It is recommended for types to be instantiable.
133      * <p>
134      * The given type may have its own dependencies that will have to be
135      * satisfied by other bindings.
136      * <p>It is permissible to have two bindings forming a chain, like
137      * <code>A &rarr; B &rarr; C</code>. The {@code chained} parameter controls
138      * whether the chain is followed.  If {@code chained == false} for the {@code A &rarr; B}
139      * binding, then the {@code B &rarr; C} binding is not followed (and the {@code A &rarr; B}
140      * binding is called <em>terminal</em>).
141      * 
142      * @param impl The implementation type
143      * @param chained Whether further binding lookup will be done on the implementation type.
144      *                {@code true} allows lookup, {@code false} creates a terminal binding.
145      */
146     void to(@Nonnull Class<? extends T> impl, boolean chained);
147 
148     /**
149      * Bind to an implementation type non-terminally.  This calls {@link #to(Class, boolean)}
150      * as {@code this.to(impl, true)}.
151      *
152      * @param impl The implementation type.
153      */
154     void to(@Nonnull Class<? extends T> impl);
155 
156     /**
157      * Complete this binding by specifying an instance to use. The instance will
158      * be used to satisfy matched injection points. Because the instance never
159      * changes, any cache policy assigned by {@link #shared()} or
160      * {@link #unshared()} is effectively ignored.
161      * 
162      * @param instance The instance to use. If {@code null}, binds explicitly to
163      *                 null.
164      */
165     void to(@Nullable T instance);
166 
167     /**
168      * Complete this binding by specifying a Provider class to be instantiated
169      * and used to create instances of type T. The Provider class may have its
170      * own dependencies that will be resolved by the injector.
171      * 
172      * @param provider The provider type that will satisfy this binding
173      */
174     void toProvider(@Nonnull Class<? extends Provider<? extends T>> provider);
175 
176     /**
177      * Complete this binding by specifying a Provider instance that will be used
178      * to create instances of type T to satisfy this binding.
179      * 
180      * @param provider The provider instance
181      */
182     void toProvider(@Nonnull Provider<? extends T> provider);
183 
184 
185     /**
186      * Complete this binding by explicitly binding to {@code null}. The resulting
187      * bindings may not create an instantiable graph, as non-nullable injection points
188      * still require a non-null instance.
189      */
190     void toNull();
191 
192     /**
193      * Complete this binding by explicitly binding to {@code null} with a type.
194      * @param type The type of {@code null} to bind.
195      * @see #toNull()
196      */
197     void toNull(Class<? extends T> type);
198 
199     /**
200      * Bind this binding directly to a satisfaction.
201      *
202      * <p><strong>Note:</strong> this method is intended for use by applications that extend Grapht,
203      * or for bindings to other JVM languages. Most applications will have no use for this method,
204      * and developers consider if one of the other methods is more applicable for their situation.
205      * </p>
206      *
207      * <p>Bindings to satisfactions are always {@linkplain org.grouplens.grapht.solver.BindRule#isTerminal() terminal}.
208      * </p>
209      *
210      * @param sat The satisfaction to bind to.
211      */
212     void toSatisfaction(@Nonnull Satisfaction sat);
213 }