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