Skip to content

Commit

Permalink
Merge pull request #64 from inversify/issue-674
Browse files Browse the repository at this point in the history
  • Loading branch information
remojansen authored Dec 5, 2017
2 parents 24f7dff + 23d7fae commit cafc953
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 10 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,35 @@ class Shuriken implements ThrowableWeapon {

```

### Using @provide multiple times

If you try to apply `@provide` multiple times:

```ts
@provide("Ninja")
@provide("SilentNinja")
class Ninja {
// ...
}
```

The library will throw an exception:

> Cannot apply @injectable decorator multiple times. Please use @provide(ID, true) if you are trying to declare multiple bindings!
We throw an exception to ensure that you are are not trying to apply `@provide` multiple times by mistake.

You can overcome this by passing the `force` argument to `@provide`:

```ts
@provide("Ninja", true)
@provide("SilentNinja", true)
class Ninja {
// ...
}
```


### Using classes, string literals & symbols as identifiers
When you invoke `@provide` using classes:

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "inversify-binding-decorators",
"version": "3.0.1",
"version": "3.1.0",
"description": "An utility that allows developers to declare InversifyJS bindings using ES2016 decorators",
"main": "lib/index.js",
"jsnext:main": "es/index.js",
Expand Down
34 changes: 26 additions & 8 deletions src/decorator/provide.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
import { decorate, injectable } from "inversify";
import { decorate, injectable, METADATA_KEY } from "inversify";
import { interfaces } from "inversify";

function provide(container: interfaces.Container) {

// function is named for testing
return function _provide(serviceIdentifier: interfaces.ServiceIdentifier<any>) {
return function _provide(
serviceIdentifier: interfaces.ServiceIdentifier<any>,
force?: boolean
) {
let bindingWhenOnSyntax = container.bind<any>(serviceIdentifier).to(<any>null);
return function (target: any) {
decorate(injectable(), target);
let binding: interfaces.Binding<any> = (<any>bindingWhenOnSyntax)._binding;
binding.implementationType = target;
return target;

const isAlreadyDecorated = Reflect.hasOwnMetadata(METADATA_KEY.PARAM_TYPES, target);
const redecorateWithInject = force === true;

if (redecorateWithInject === true && isAlreadyDecorated === false) {
decorate(injectable(), target);
} else if (redecorateWithInject === true && isAlreadyDecorated === true) {
// Do nothing
} else {
try {
decorate(injectable(), target);
} catch (e) {
throw new Error(`${e.message} ` +
"Please use @provide(ID, true) if you are trying to declare multiple bindings!");
}
}

let binding: interfaces.Binding<any> = (<any>bindingWhenOnSyntax)._binding;
binding.implementationType = target;
return target;

};
};
}
Expand Down
34 changes: 34 additions & 0 deletions test/decorator/provide.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,38 @@ describe("provide", () => {

});

it("Should throw if applied more than once without force flag", () => {

const myContainer = new Container();
const provide = _provide(myContainer);

function shouldThrow() {
@provide("Ninja")
@provide("SilentNinja")
class Ninja {}
return Ninja;
}

expect(shouldThrow).to.throw(
"Cannot apply @injectable decorator multiple times. " +
"Please use @provide(ID, true) if you are trying to declare multiple bindings!");

});

it("Should work if applied more than once with force flag", () => {

const myContainer = new Container();
const provide = _provide(myContainer);

function shouldThrow() {
@provide("Ninja", true)
@provide("SilentWarrior", true)
class Ninja {}
return Ninja;
}

expect(shouldThrow).not.to.throw();

});

});
1 change: 0 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"no-switch-case-fall-through": false,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"object-literal-sort-keys": true,
"one-line": [true,
Expand Down

0 comments on commit cafc953

Please sign in to comment.