Skip to content

Commit

Permalink
paramsAlias, some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
matuszeman committed May 19, 2017
1 parent 1b27881 commit f647b71
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 92 deletions.
22 changes: 22 additions & 0 deletions README.hbs.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,25 @@ dic.getAsync('server').then(server => {
});
});
```

# Development

Run the command below to builds es5 folder and README.md.

```
npm run build
```

## Tests

```
npm test
```

# Contribute

Please feel free to submit an issue/PR or contact me at matus.zeman@gmail.com.

# License

[MIT](LICENSE)
81 changes: 61 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ dic.getAsync('myApp').then(app => {
</dd>
</dl>

## Typedefs

<dl>
<dt><a href="#defOpts">defOpts</a> : <code>Object</code></dt>
<dd></dd>
</dl>

<a name="DicClassLoader"></a>

## DicClassLoader
Expand Down Expand Up @@ -223,10 +230,10 @@ For more usage examples see: [instance](#Dic+instance), [class](#Dic+class), [fa

* [Dic](#Dic)
* [new Dic(options)](#new_Dic_new)
* [.asyncFactory(name, factory)](#Dic+asyncFactory)
* [.factory(name, factory)](#Dic+factory)
* [.asyncFactory(name, factory, [opts])](#Dic+asyncFactory)
* [.factory(name, factory, [opts])](#Dic+factory)
* [.instance(name, instance)](#Dic+instance)
* [.class(name, classDef, opts)](#Dic+class)
* [.class(name, classDef, [opts])](#Dic+class)
* [.asyncInit()](#Dic+asyncInit)
* [.has(name)](#Dic+has) ⇒ <code>boolean</code>
* [.get(name)](#Dic+get) ⇒ <code>\*</code>
Expand Down Expand Up @@ -264,17 +271,18 @@ const myService = dic.get('myService');
```
<a name="Dic+asyncFactory"></a>

### dic.asyncFactory(name, factory)
### dic.asyncFactory(name, factory, [opts])
Registers async factory.

Factory function is called asynchronously and should return an instance of the service.

**Kind**: instance method of <code>[Dic](#Dic)</code>

| Param |
| --- |
| name |
| factory |
| Param | Type |
| --- | --- |
| name | <code>String</code> |
| factory | <code>function</code> |
| [opts] | <code>[defOpts](#defOpts)</code> |

**Example**
```js
Expand All @@ -285,17 +293,18 @@ dic.asyncFactory('mongoConnection', async function(mongoConnectionOpts) {
```
<a name="Dic+factory"></a>

### dic.factory(name, factory)
### dic.factory(name, factory, [opts])
Register a factory.

The factory function should return an instance of the service.

**Kind**: instance method of <code>[Dic](#Dic)</code>

| Param |
| --- |
| name |
| factory |
| Param | Type |
| --- | --- |
| name | |
| factory | |
| [opts] | <code>[defOpts](#defOpts)</code> |

**Example**
```js
Expand Down Expand Up @@ -324,17 +333,16 @@ dic.instance('myFunction', function(msg) { console.log(msg) });
```
<a name="Dic+class"></a>

### dic.class(name, classDef, opts)
### dic.class(name, classDef, [opts])
Register a class

**Kind**: instance method of <code>[Dic](#Dic)</code>

| Param | Type | Description |
| --- | --- | --- |
| name | | |
| classDef | | |
| opts | <code>Object</code> | |
| opts.asyncInit | <code>boolean</code> &#124; <code>string</code> | If true default asyncInit() function is used. If string, provided function is called on [asyncInit](#Dic+asyncInit). |
| Param | Type |
| --- | --- |
| name | |
| classDef | |
| [opts] | <code>[defOpts](#defOpts)</code> |

**Example**
```js
Expand Down Expand Up @@ -580,6 +588,17 @@ See [createInstance](#Dic+createInstance)
| def.inject | <code>Object</code> | |
| opts | <code>Object</code> | |

<a name="defOpts"></a>

## defOpts : <code>Object</code>
**Kind**: global typedef
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| asyncInit | <code>string</code> &#124; <code>boolean</code> | If true default asyncInit() function is used. If string, provided function is called on [asyncInit](#Dic+asyncInit). |
| paramsAlias | <code>Object</code> | Use to alias class constructor or factory parameters. E.g. `{ serviceA: 'serviceB' }` injects `serviceB` instance instead of `serviceA` to the class constructor/factory. |


# Framework usage examples

Expand Down Expand Up @@ -714,3 +733,25 @@ dic.getAsync('server').then(server => {
});
});
```

# Development

Run the command below to builds es5 folder and README.md.

```
npm run build
```

## Tests

```
npm test
```

# Contribute

Please feel free to submit an issue/PR or contact me at matus.zeman@gmail.com.

# License

[MIT](LICENSE)
80 changes: 41 additions & 39 deletions es5/dic.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ var Dic = function () {
presence: 'required'
}));
this.instances = {};
this.loaders = [];
this.parent = null;
this.parentOptions = {};
this.children = {};
Expand All @@ -89,13 +88,6 @@ var Dic = function () {
console.log(this.getDicInstanceName() + ': ' + msg);
}
}
}, {
key: 'registerLoader',
value: function registerLoader(loader) {
var loadInstances = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

this.loaders.push(loader);
}

/**
* Registers async factory.
Expand All @@ -109,14 +101,16 @@ var Dic = function () {
* return await MongoClient.connect(mongoConnectionOpts.url);
* });
*
* @param name
* @param factory
* @param {String} name
* @param {Function} factory
* @param {defOpts} [opts]
*/

}, {
key: 'registerAsyncFactory',
value: function registerAsyncFactory(name, factory, opts) {
opts = opts || {};
value: function registerAsyncFactory(name, factory) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

this.log('Adding async factory "' + name + '" Options: ', opts); //XXX

if (!opts.params) {
Expand Down Expand Up @@ -150,6 +144,7 @@ var Dic = function () {
*
* @param name
* @param factory
* @param {defOpts} [opts]
*/

}, {
Expand Down Expand Up @@ -244,8 +239,7 @@ var Dic = function () {
*
* @param name
* @param classDef
* @param {Object} opts
* @param {boolean|string} opts.asyncInit If true default asyncInit() function is used. If string, provided function is called on {@link Dic#asyncInit}.
* @param {defOpts} [opts]
*/

}, {
Expand Down Expand Up @@ -742,10 +736,10 @@ var Dic = function () {
this.throwError('Use dic.createInstanceAsync() instead', opts.stack);
break;
case 'factory':
return (_def = def).factory.apply(_def, (0, _toConsumableArray3.default)(this.getServices(def.params, def.inject, opts)));
return (_def = def).factory.apply(_def, (0, _toConsumableArray3.default)(this.getServices(def, opts)));
break;
case 'class':
return new (Function.prototype.bind.apply(def.class, [null].concat((0, _toConsumableArray3.default)(this.getServices(def.params, def.inject, opts)))))();
return new (Function.prototype.bind.apply(def.class, [null].concat((0, _toConsumableArray3.default)(this.getServices(def, opts)))))();
break;
default:
this.throwError('Unknown instance def type: ' + def.type, opts.stack);
Expand Down Expand Up @@ -787,7 +781,7 @@ var Dic = function () {
_context3.t2 = _def2;
_context3.t3 = _toConsumableArray3.default;
_context3.next = 9;
return this.getServicesAsync(def.params, def.inject, opts);
return this.getServicesAsync(def, opts);

case 9:
_context3.t4 = _context3.sent;
Expand All @@ -803,7 +797,7 @@ var Dic = function () {
_context3.t7 = _def3;
_context3.t8 = _toConsumableArray3.default;
_context3.next = 20;
return this.getServicesAsync(def.params, def.inject, opts);
return this.getServicesAsync(def, opts);

case 20:
_context3.t9 = _context3.sent;
Expand All @@ -816,7 +810,7 @@ var Dic = function () {
_context3.t13 = [null];
_context3.t14 = _toConsumableArray3.default;
_context3.next = 30;
return this.getServicesAsync(def.params, def.inject, opts);
return this.getServicesAsync(def, opts);

case 30:
_context3.t15 = _context3.sent;
Expand All @@ -842,6 +836,14 @@ var Dic = function () {

return createInstanceAsync;
}()

/**
* @typedef {Object} defOpts
* @property {string|boolean} [asyncInit] If true default asyncInit() function is used. If string, provided function is called on {@link Dic#asyncInit}.
* @property {Object} [paramsAlias] Use to alias class constructor or factory parameters.
* E.g. `{ serviceA: 'serviceB' }` injects `serviceB` instance instead of `serviceA` to the class constructor/factory.
*/

}, {
key: 'validateDef',
value: function validateDef(def) {
Expand All @@ -852,6 +854,7 @@ var Dic = function () {
factory: Joi.func(),
asyncInit: Joi.any(),
params: Joi.array(),
paramsAlias: Joi.object().default({}),
asyncFactory: Joi.func(),
inject: Joi.object().default({})
}));
Expand Down Expand Up @@ -901,44 +904,43 @@ var Dic = function () {
}
}, {
key: 'getServices',
value: function getServices(serviceNames) {
value: function getServices(def) {
var _this = this;

var inject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

if (!_.isArray(serviceNames)) {
return [];
}
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

return serviceNames.map(function (param) {
if (inject[param]) {
return inject[param];
var params = this._getDefParams(def);
return params.map(function (param) {
if (def.inject[param]) {
return def.inject[param];
}
return _this.get(param, opts);
});
}
}, {
key: 'getServicesAsync',
value: function getServicesAsync(serviceNames) {
value: function getServicesAsync(def) {
var _this2 = this;

var inject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

if (!_.isArray(serviceNames)) {
return [];
}
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

var servicesPromises = serviceNames.map(function (param) {
if (inject[param]) {
return inject[param];
var params = this._getDefParams(def);
var servicesPromises = params.map(function (param) {
if (def.inject[param]) {
return def.inject[param];
}
return _this2.getAsync(param, opts);
});

return _promise2.default.all(servicesPromises);
}
}, {
key: '_getDefParams',
value: function _getDefParams(def) {
return def.params.map(function (param) {
return _.get(def.paramsAlias, param, param);
});
}
}, {
key: '_createOpts',
value: function _createOpts(service, opts) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"name": "bb-dic",
"version": "0.7.0",
"version": "0.8.0",
"description": "A dependency injection container",
"main": "src/index.js",
"scripts": {
"test": "mocha --harmony 'src/**/*.spec.js'",
"test-watch": "mocha --harmony --watch 'src/**/*.spec.js'",
"build": "npm run es5 && npm run docs",
"es5": "babel src -d es5",
"docs": "jsdoc2md --configure jsdoc.json --template README.hbs.md \"src/**/*.js\" > README.md"
Expand Down
Loading

0 comments on commit f647b71

Please sign in to comment.