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