Comparing version 1.6.3 to 1.7.0
@@ -84,2 +84,8 @@ declare class Bottle { | ||
/** | ||
* Register a service function. If Bottle.config.strict is set to true, this method will throw an error if an injected dependency is undefined. | ||
*/ | ||
serviceFactory(name: string, factoryService: ((...any: any[]) => any), ...dependency: string[]): this; | ||
serviceFactory<T>(name: string, factoryService: ((...any: any[]) => T), ...dependency: string[]): this; | ||
/** | ||
* Add an arbitrary value to the container. | ||
@@ -102,2 +108,3 @@ */ | ||
interface IContainer { | ||
[key: string]: any; | ||
$decorator(name: string|((service: any) => any), func?: (service: any) => any): this; | ||
@@ -104,0 +111,0 @@ $register(Obj: Bottle.IRegisterableObject): this; |
;(function(undefined) { | ||
'use strict'; | ||
/** | ||
* BottleJS v1.6.3 - 2017-12-06 | ||
* BottleJS v1.7.0 - 2018-01-29 | ||
* A powerful dependency injection micro container | ||
* | ||
* Copyright (c) 2017 Stephen Young | ||
* Copyright (c) 2018 Stephen Young | ||
* Licensed MIT | ||
*/ | ||
/** | ||
* String constants | ||
*/ | ||
var DELIMITER = '.'; | ||
var FUNCTION_TYPE = 'function'; | ||
var STRING_TYPE = 'string'; | ||
var GLOBAL_NAME = '__global__'; | ||
var PROVIDER_SUFFIX = 'Provider'; | ||
@@ -69,3 +77,3 @@ /** | ||
var getNestedService = function getNestedService(fullname) { | ||
return fullname.split('.').reduce(getNested, this); | ||
return fullname.split(DELIMITER).reduce(getNested, this); | ||
}; | ||
@@ -81,3 +89,3 @@ | ||
var constant = function constant(name, value) { | ||
var parts = name.split('.'); | ||
var parts = name.split(DELIMITER); | ||
name = parts.pop(); | ||
@@ -106,11 +114,11 @@ defineConstant.call(parts.reduce(setValueObject, this.container), name, value); | ||
var parts, name; | ||
if (typeof fullname === 'function') { | ||
if (typeof fullname === FUNCTION_TYPE) { | ||
func = fullname; | ||
fullname = '__global__'; | ||
fullname = GLOBAL_NAME; | ||
} | ||
parts = fullname.split('.'); | ||
parts = fullname.split(DELIMITER); | ||
name = parts.shift(); | ||
if (parts.length) { | ||
getNestedBottle.call(this, name).decorator(parts.join('.'), func); | ||
getNestedBottle.call(this, name).decorator(parts.join(DELIMITER), func); | ||
} else { | ||
@@ -240,11 +248,11 @@ if (!this.decorators[name]) { | ||
var parts, name; | ||
if (typeof fullname === 'function') { | ||
if (typeof fullname === FUNCTION_TYPE) { | ||
func = fullname; | ||
fullname = '__global__'; | ||
fullname = GLOBAL_NAME; | ||
} | ||
parts = fullname.split('.'); | ||
parts = fullname.split(DELIMITER); | ||
name = parts.shift(); | ||
if (parts.length) { | ||
getNestedBottle.call(this, name).middleware(parts.join('.'), func); | ||
getNestedBottle.call(this, name).middleware(parts.join(DELIMITER), func); | ||
} else { | ||
@@ -277,3 +285,3 @@ if (!this.middlewares[name]) { | ||
var instance; | ||
if (typeof name === 'string') { | ||
if (typeof name === STRING_TYPE) { | ||
instance = bottles[name]; | ||
@@ -293,3 +301,3 @@ if (!instance) { | ||
var clear = function clear(name) { | ||
if (typeof name === 'string') { | ||
if (typeof name === STRING_TYPE) { | ||
delete bottles[name]; | ||
@@ -321,4 +329,4 @@ } else { | ||
var parts, name; | ||
parts = fullname.split('.'); | ||
if (this.providerMap[fullname] && parts.length === 1 && !this.container[fullname + 'Provider']) { | ||
parts = fullname.split(DELIMITER); | ||
if (this.providerMap[fullname] && parts.length === 1 && !this.container[fullname + PROVIDER_SUFFIX]) { | ||
return console.error(fullname + ' provider already instantiated.'); | ||
@@ -332,3 +340,3 @@ } | ||
if (parts.length) { | ||
getNestedBottle.call(this, name).provider(parts.join('.'), Provider); | ||
getNestedBottle.call(this, name).provider(parts.join(DELIMITER), Provider); | ||
return this; | ||
@@ -362,3 +370,3 @@ } | ||
middlewares = this.middlewares; | ||
providerName = name + 'Provider'; | ||
providerName = name + PROVIDER_SUFFIX; | ||
@@ -428,3 +436,3 @@ properties = Object.create(null); | ||
delete this.container[name]; | ||
delete this.container[name + 'Provider']; | ||
delete this.container[name + PROVIDER_SUFFIX]; | ||
}; | ||
@@ -440,3 +448,3 @@ | ||
Object.keys(this.originalProviders).forEach(function resetPrvider(provider) { | ||
var parts = provider.split('.'); | ||
var parts = provider.split(DELIMITER); | ||
if (parts.length > 1) { | ||
@@ -466,3 +474,10 @@ parts.forEach(removeProviderMap, getNestedBottle.call(this, parts[0])); | ||
/** | ||
* Register a service inside a generic factory. | ||
* Register a function service | ||
*/ | ||
var serviceFactory = function serviceFactory(name, factoryService) { | ||
return createService.apply(this, [name, factoryService, false].concat(slice.call(arguments, 2))); | ||
}; | ||
/** | ||
* Register a class service | ||
* | ||
@@ -474,12 +489,23 @@ * @param String name | ||
var service = function service(name, Service) { | ||
var deps = arguments.length > 2 ? slice.call(arguments, 2) : null; | ||
return createService.apply(this, [name, Service, true].concat(slice.call(arguments, 2))); | ||
}; | ||
/** | ||
* Private helper for creating service and service factories. | ||
* | ||
* @param String name | ||
* @param Function Service | ||
* @return Bottle | ||
*/ | ||
var createService = function createService(name, Service, isClass) { | ||
var deps = arguments.length > 3 ? slice.call(arguments, 3) : []; | ||
var bottle = this; | ||
return factory.call(this, name, function GenericFactory() { | ||
var ServiceCopy = Service; | ||
if (deps) { | ||
var args = deps.map(getNestedService, bottle.container); | ||
args.unshift(Service); | ||
ServiceCopy = Service.bind.apply(Service, args); | ||
var serviceFactory = Service; // alias for jshint | ||
var args = deps.map(getNestedService, bottle.container); | ||
if (!isClass) { | ||
return serviceFactory.apply(null, args); | ||
} | ||
return new ServiceCopy(); | ||
return new (Service.bind.apply(Service, [null].concat(args)))(); | ||
}); | ||
@@ -497,3 +523,3 @@ }; | ||
var parts; | ||
parts = name.split('.'); | ||
parts = name.split(DELIMITER); | ||
name = parts.pop(); | ||
@@ -579,2 +605,3 @@ defineValue.call(parts.reduce(setValueObject, this.container), name, val); | ||
service : service, | ||
serviceFactory : serviceFactory, | ||
value : value | ||
@@ -649,3 +676,3 @@ }; | ||
*/ | ||
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { | ||
if (typeof define === FUNCTION_TYPE && typeof define.amd === 'object' && define.amd) { | ||
root.Bottle = Bottle; | ||
@@ -652,0 +679,0 @@ define(function() { return Bottle; }); |
{ | ||
"name": "bottlejs", | ||
"version": "1.6.3", | ||
"version": "1.7.0", | ||
"description": "A powerful dependency injection micro container", | ||
@@ -5,0 +5,0 @@ "main": "dist/bottle.js", |
@@ -418,2 +418,26 @@ | ||
#### serviceFactory(name, factoryService [, dependency [, ...]]) | ||
Used to register a service factory function. Works exactly like `factory` except the factory arguments will be injected instead of receiving the `container`. This is useful when implementing the Module Pattern or adding dependencies to your Higher Order Functions. | ||
```js | ||
function packageKeg(Barrel, Beer, Love) { | ||
Barrel.add(Beer, Love); | ||
return { | ||
tap : function() { | ||
return Barrel.dispense(); | ||
} | ||
}; | ||
} | ||
bottle.serviceFactory('Keg', packageKeg, 'Barrel', 'Beer', 'Love'); | ||
``` | ||
If `Bottle.config.strict` is set to `true`, this method will throw an error if an injected dependency is `undefined`. | ||
Param | Type | Details | ||
:--------------------------------|:-----------|:-------- | ||
**name** | *String* | The name of the service. Must be unique to each Bottle instance. | ||
**serviceFactory** | *Function* | A function that will be invoked to create the service object/value. | ||
**dependency**<br />*(optional)* | *String* | An optional name for a dependency to be passed to the service function. A dependency will be passed to the service function for each name passed to `Bottle#serviceFactory` in the order they are listed. | ||
#### value(name, val) | ||
@@ -420,0 +444,0 @@ |
46001
702
454
8