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