Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(context): improve @inject.setter and add @inject.binding #2657

Merged
merged 1 commit into from Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 77 additions & 1 deletion docs/site/Decorators_inject.md
Expand Up @@ -126,7 +126,19 @@ class MyControllerWithGetter {

`@inject.setter` injects a setter function to set the bound value of the key.

Syntax: `@inject.setter(bindingKey: string)`.
Syntax: `@inject.setter(bindingKey: BindingAddress, {bindingCreation?: ...})`.

The `setter` function injected has the following signature:

```ts
export type Setter<T> = (value?: T) => void;
```

The binding resolution/creation is controlled by `bindingCreation` option. See
[@inject.binding](#injectbinding) for possible settings.

The following example shows the usage of `@inject.setter` and the injected
setter function.

```ts
export class HelloController {
Expand All @@ -143,6 +155,70 @@ export class HelloController {
}
```

Please note the setter function simply binds a `value` to the underlying binding
using `binding.to(value)`.

To set other types of value providers such as `toDynamicValue`or `toClass`, use
`@inject.binding` instead.

### @inject.binding

`@inject.binding` injects a binding for the given key. It can be used to bind
various types of value providers to the underlying binding or configure the
binding. This is an advanced form of `@inject.setter`, which only allows to set
a constant value (using `Binding.to(value)` behind the scene) to the underlying
binding.

Syntax: `@inject.binding(bindingKey: BindingAddress, {bindingCreation?: ...})`.

```ts
export class HelloController {
constructor(
@inject.binding('greeting') private greetingBinding: Binding<string>,
) {}

@get('/hello')
async greet() {
// Bind `greeting` to a factory function that reads default greeting
// from a file or database
this.greetingBinding.toDynamicValue(() => readDefaultGreeting());
return await this.greetingBinding.get<string>(this.greetingBinding.key);
}
}
```

The `@inject.binding` takes an optional `metadata` object which can contain
`bindingCreation` to control how underlying binding is resolved or created based
on the following values:

```ts
/**
* Policy to control if a binding should be created for the context
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a good idea to duplicate our API docs here? Can we point readers to http://apidocs.loopback.io/@loopback%2fdocs/context.html instead?

*/
export enum BindingCreationPolicy {
/**
* Always create a binding with the key for the context
*/
ALWAYS_CREATE = 'Always',
/**
* Never create a binding for the context. If the key is not bound in the
* context, throw an error.
*/
NEVER_CREATE = 'Never',
/**
* Create a binding if the key is not bound in the context. Otherwise, return
* the existing binding.
*/
CREATE_IF_NOT_BOUND = 'IfNotBound',
}
```

For example:

```ts
@inject.setter('binding-key', {bindingCreation: BindingCreationPolicy.NEVER_CREATES})
```

### @inject.tag

`@inject.tag` injects an array of values by a pattern or regexp to match binding
Expand Down
1 change: 1 addition & 0 deletions docs/site/Dependency-injection.md
Expand Up @@ -245,6 +245,7 @@ There are a few special decorators from the `inject` namespace.

- [`@inject.getter`](Decorators_inject.md#@inject.getter)
- [`@inject.setter`](Decorators_inject.md#@inject.setter)
- [`@inject.binding`](Decorators_inject.md#@inject.binding)
- [`@inject.context`](Decorators_inject.md#@inject.context)
- [`@inject.tag`](Decorators_inject.md#@inject.tag)
- [`@inject.view`](Decorators_inject.md#@inject.view)
Expand Down
Expand Up @@ -3,13 +3,13 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {expect} from '@loopback/testlab';
import {Context, instantiateClass} from '@loopback/context';
import {Request} from '@loopback/rest';
import {AuthenticateFn, UserProfile, AuthenticationBindings} from '../../..';
import {MockStrategy} from '../fixtures/mock-strategy';
import {expect} from '@loopback/testlab';
import {Strategy} from 'passport';
import {AuthenticateFn, AuthenticationBindings, UserProfile} from '../../..';
import {AuthenticateActionProvider} from '../../../providers';
import {MockStrategy} from '../fixtures/mock-strategy';

describe('AuthenticateActionProvider', () => {
describe('constructor()', () => {
Expand Down