| 126 | * |
| 127 | */ |
| 128 | export function inject( |
| 129 | bindingSelector: BindingSelector, |
| 130 | metadata?: InjectionMetadata, |
| 131 | resolve?: ResolverFunction, |
| 132 | ) { |
| 133 | if (typeof bindingSelector === 'function' && !resolve) { |
| 134 | resolve = resolveValuesByFilter; |
| 135 | } |
| 136 | const injectionMetadata = Object.assign({decorator: '@inject'}, metadata); |
| 137 | if (injectionMetadata.bindingComparator && !resolve) { |
| 138 | throw new Error('Binding comparator is only allowed with a binding filter'); |
| 139 | } |
| 140 | if (!bindingSelector && typeof resolve !== 'function') { |
| 141 | throw new Error( |
| 142 | 'A non-empty binding selector or resolve function is required for @inject', |
| 143 | ); |
| 144 | } |
| 145 | return function markParameterOrPropertyAsInjected( |
| 146 | target: Object, |
| 147 | member: string | undefined, |
| 148 | methodDescriptorOrParameterIndex?: |
| 149 | | TypedPropertyDescriptor<BoundValue> |
| 150 | | number, |
| 151 | ) { |
| 152 | if (typeof methodDescriptorOrParameterIndex === 'number') { |
| 153 | // The decorator is applied to a method parameter |
| 154 | // Please note propertyKey is `undefined` for constructor |
| 155 | const paramDecorator: ParameterDecorator = |
| 156 | ParameterDecoratorFactory.createDecorator<Injection>( |
| 157 | INJECT_PARAMETERS_KEY, |
| 158 | { |
| 159 | target, |
| 160 | member, |
| 161 | methodDescriptorOrParameterIndex, |
| 162 | bindingSelector, |
| 163 | metadata: injectionMetadata, |
| 164 | resolve, |
| 165 | }, |
| 166 | // Do not deep clone the spec as only metadata is mutable and it's |
| 167 | // shallowly cloned |
| 168 | {cloneInputSpec: false, decoratorName: injectionMetadata.decorator}, |
| 169 | ); |
| 170 | paramDecorator(target, member!, methodDescriptorOrParameterIndex); |
| 171 | } else if (member) { |
| 172 | // Property or method |
| 173 | if (target instanceof Function) { |
| 174 | throw new Error( |
| 175 | '@inject is not supported for a static property: ' + |
| 176 | DecoratorFactory.getTargetName(target, member), |
| 177 | ); |
| 178 | } |
| 179 | if (methodDescriptorOrParameterIndex) { |
| 180 | // Method |
| 181 | throw new Error( |
| 182 | '@inject cannot be used on a method: ' + |
| 183 | DecoratorFactory.getTargetName( |
| 184 | target, |
| 185 | member, |