1 /*
2  * Copyright 2014 Google Inc. All rights reserved.
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 
17 #ifndef FRUIT_INJECTOR_H
18 #define FRUIT_INJECTOR_H
19 
20 // This include is not required here, but having it here shortens the include trace in error messages.
21 #include <fruit/impl/injection_errors.h>
22 
23 #include <fruit/component.h>
24 #include <fruit/normalized_component.h>
25 #include <fruit/provider.h>
26 #include <fruit/impl/meta_operation_wrappers.h>
27 
28 namespace fruit {
29 
30 /**
31  * An injector is a class constructed from a component that performs the needed injections and manages the lifetime of
32  * the created objects.
33  * An injector does *not* need to specify all types bound in the component; you can only specify the "root" type(s) and
34  * the injector will also create and store the instances of classes that are needed (directly or indirectly) to inject
35  * the root types.
36  *
37  * Example usage:
38  *
39  * Component<Foo, Bar> getFooBarComponent() {
40  *   ...
41  * }
42  *
43  * Injector<Foo, Bar> injector(getFooBarComponent);
44  * Foo* foo = injector.get<Foo*>();
45  * Bar* bar(injector); // Equivalent to: Bar* bar = injector.get<Bar*>();
46  */
47 template <typename... P>
48 class Injector {
49 public:
50   // Moving injectors is allowed.
51   Injector(Injector&&) = default;
52 
53   // Copying injectors is forbidden.
54   Injector(const Injector&) = delete;
55 
56   /**
57    * This creates an injector from a component function (that can optionally have parameters).
58    *
59    * Args and FormalArgs (if any) must be the same types; or to be precise, each type in Args must be convertible into
60    * the corresponding type in FormalArgs.
61    *
62    * Example usage:
63    *
64    * Component<Foo, Bar> getFooBarComponent() {
65    *   ...
66    * }
67    *
68    * Injector<Foo, Bar> injector(getFooBarComponent);
69    * Foo* foo = injector.get<Foo*>();
70    * Bar* bar(injector); // Equivalent to: Bar* bar = injector.get<Bar*>();
71    *
72    * Example usage with arguments:
73    *
74    * Component<Foo, Bar> getFooBarComponent(int n, double d) {
75    *   ...
76    * }
77    *
78    * Injector<Foo, Bar> injector(getFooBarComponent, 10, 3.14);
79    * Foo* foo = injector.get<Foo*>();
80    */
81   template <typename... FormalArgs, typename... Args>
82   Injector(Component<P...> (*)(FormalArgs...), Args&&... args);
83 
84   /**
85    * This creates an injector from a normalized component and a component function.
86    * See the documentation of NormalizedComponent for more details.
87    *
88    * Args and FormalArgs (if any) must be the same types; or to be precise, each type in Args must be convertible into
89    * the corresponding type in FormalArgs.
90    *
91    * The NormalizedComponent can have requirements, but the Component can't.
92    * The NormalizedComponent must remain valid during the lifetime of any Injector object constructed with it.
93    *
94    * Example usage:
95    *
96    * // In the global scope.
97    * Component<Request> getRequestComponent(Request* request) {
98    *   return fruit::createComponent()
99    *       .bindInstance(*request);
100    * }
101    *
102    * // At startup (e.g. inside main()).
103    * NormalizedComponent<Required<Request>, Bar, Bar2> normalizedComponent = ...;
104    *
105    * ...
106    * for (...) {
107    *   // For each request.
108    *   Request request = ...;
109    *
110    *   Injector<Foo, Bar> injector(normalizedComponent, getRequestComponent, &request);
111    *   Foo* foo = injector.get<Foo*>();
112    *   ...
113    * }
114    */
115   template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs,
116             typename... Args>
117   Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
118            Component<ComponentParams...> (*)(FormalArgs...), Args&&... args);
119 
120   /**
121    * Deleted constructor, to ensure that constructing an Injector from a temporary NormalizedComponent doesn't compile.
122    */
123   template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs,
124             typename... Args>
125   Injector(NormalizedComponent<NormalizedComponentParams...>&& normalized_component,
126            Component<ComponentParams...> (*)(FormalArgs...), Args&&... args) = delete;
127 
128   /**
129    * Returns an instance of the specified type. For any class C in the Injector's template parameters, the following
130    * variations are allowed:
131    *
132    * get<C>()
133    * get<C*>()
134    * get<C&>()
135    * get<const C*>()
136    * get<const C&>()
137    * get<shared_ptr<C>>()
138    * get<Provider<C>>()
139    * get<Provider<const C>>()
140    * get<Annotated<Annotation, C>>()                   (for any type `Annotation')
141    * get<Annotated<Annotation, C*>>()                  (for any type `Annotation')
142    * get<Annotated<Annotation, C&>>()                  (for any type `Annotation')
143    * get<Annotated<Annotation, const C*>>()            (for any type `Annotation')
144    * get<Annotated<Annotation, const C&>>()            (for any type `Annotation')
145    * get<Annotated<Annotation, shared_ptr<C>>>()       (for any type `Annotation')
146    * get<Annotated<Annotation, Provider<C>>>()         (for any type `Annotation')
147    * get<Annotated<Annotation, Provider<const C>>>()   (for any type `Annotation')
148    *
149    * For any "const C" in the Injector's template parameters, only a subset of those are allowed, specifically:
150    *
151    * get<C>()
152    * get<const C*>()
153    * get<const C&>()
154    * get<Provider<const C>>()
155    * get<Annotated<Annotation, C>>()                   (for any type `Annotation')
156    * get<Annotated<Annotation, const C*>>()            (for any type `Annotation')
157    * get<Annotated<Annotation, const C&>>()            (for any type `Annotation')
158    * get<Annotated<Annotation, Provider<const C>>>()   (for any type `Annotation')
159    *
160    * With a non-annotated parameter T, this returns a T.
161    * With an annotated parameter AnnotatedT=Annotated<Annotation, T>, this returns a T.
162    * E.g. if you want to inject a pointer for an annotated type, you can use this as follows:
163    *
164    * T* instance = injector.get<Annotated<Annotation, T*>>();
165    *
166    * The shared_ptr versions come with a slight performance hit, prefer injecting pointers or references if possible.
167    * Calling get<> repeatedly for the same class with the same injector will return the same instance.
168    */
169   template <typename T>
170   fruit::impl::RemoveAnnotations<T> get();
171 
172   /**
173    * This is a convenient way to call get(). E.g.:
174    *
175    * MyInterface* x(injector);
176    *
177    * is equivalent to:
178    *
179    * MyInterface* x = injector.get<MyInterface*>();
180    *
181    * Note that this can't be used to inject an annotated type, i.e. this does NOT work:
182    *
183    * fruit::Annotated<SomeAnnotation, SomeClass> foo(injector);
184    *
185    * Because foo would be of type fruit::Annotated, not of type SomeClass. In that case you must use get() instead,
186    * e.g.:
187    *
188    * SomeClass* foo = injector.get<fruit::Annotated<SomeAnnotation, SomeClass*>>();;
189    */
190   template <typename T>
191   explicit operator T();
192 
193   /**
194    * Gets all multibindings for a type T.
195    *
196    * Multibindings are independent from bindings; so if there is a (normal) binding for T, that is not returned.
197    * This returns an empty vector if there are no multibindings.
198    *
199    * With a non-annotated parameter T, this returns a const std::vector<T*>&.
200    * With an annotated parameter AnnotatedT=Annotated<Annotation, T>, this returns a const std::vector<T*>&.
201    */
202   template <typename T>
203   const std::vector<fruit::impl::RemoveAnnotations<T>*>& getMultibindings();
204 
205   /**
206    * This method is deprecated since Fruit injectors can now be accessed concurrently by multiple threads. This will be
207    * removed in a future Fruit release.
208    *
209    * Eagerly injects all reachable bindings and multibindings of this injector.
210    * This only creates instances of the types that are either:
211    * - exposed by this Injector (i.e. in the Injector's type parameters)
212    * - bound by a multibinding
213    * - needed to inject one of the above (directly or indirectly)
214    *
215    * Unreachable bindings (i.e. bindings that are not exposed by this Injector, and that are not used by any reachable
216    * binding) are not processed. Bindings that are only used lazily, using a Provider, are NOT eagerly injected.
217    *
218    * Also note that this guarantee doesn't apply to Providers.
219    */
220   FRUIT_DEPRECATED_DECLARATION(void eagerlyInjectAll());
221 
222 private:
223   using Check1 = typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<
224       fruit::impl::meta::CheckNoRequiredTypesInInjectorArguments(fruit::impl::meta::Type<P>...)>>::type;
225   // Force instantiation of Check1.
226   static_assert(true || sizeof(Check1), "");
227 
228   using Comp = fruit::impl::meta::Eval<fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<P>...)>;
229 
230   using Check2 = typename fruit::impl::meta::CheckIfError<Comp>::type;
231   using VoidType = fruit::impl::meta::Type<void>;
232   // Force instantiation of Check2.
233   static_assert(true || sizeof(Check2), "");
234   using Check3 = typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::If(
235       fruit::impl::meta::Not(fruit::impl::meta::IsEmptySet(typename Comp::RsSuperset)),
236       fruit::impl::meta::ConstructErrorWithArgVector(fruit::impl::InjectorWithRequirementsErrorTag,
237                                                      fruit::impl::meta::SetToVector(typename Comp::RsSuperset)),
238       VoidType)>>::type;
239   // Force instantiation of Check3.
240   static_assert(true || sizeof(Check3), "");
241 
242   friend struct fruit::impl::InjectorAccessorForTests;
243 
244   std::unique_ptr<fruit::impl::InjectorStorage> storage;
245 };
246 
247 } // namespace fruit
248 
249 #include <fruit/impl/injector.defn.h>
250 
251 #endif // FRUIT_INJECTOR_H
252