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 → B → C</code>. The {@code chained} parameter controls
138 * whether the chain is followed. If {@code chained == false} for the {@code A → B}
139 * binding, then the {@code B → C} binding is not followed (and the {@code A → 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 }