|
1 | 1 | ;(function(undefined) { |
2 | 2 | 'use strict'; |
3 | 3 | /** |
4 | | - * BottleJS v1.6.3 - 2017-12-06 |
| 4 | + * BottleJS v1.7.0 - 2018-01-29 |
5 | 5 | * A powerful dependency injection micro container |
6 | 6 | * |
7 | | - * Copyright (c) 2017 Stephen Young |
| 7 | + * Copyright (c) 2018 Stephen Young |
8 | 8 | * Licensed MIT |
9 | 9 | */ |
| 10 | + /** |
| 11 | + * String constants |
| 12 | + */ |
| 13 | + var DELIMITER = '.'; |
| 14 | + var FUNCTION_TYPE = 'function'; |
| 15 | + var STRING_TYPE = 'string'; |
| 16 | + var GLOBAL_NAME = '__global__'; |
| 17 | + var PROVIDER_SUFFIX = 'Provider'; |
10 | 18 |
|
11 | 19 | /** |
12 | 20 | * Unique id counter; |
|
66 | 74 | * @return Service |
67 | 75 | */ |
68 | 76 | var getNestedService = function getNestedService(fullname) { |
69 | | - return fullname.split('.').reduce(getNested, this); |
| 77 | + return fullname.split(DELIMITER).reduce(getNested, this); |
70 | 78 | }; |
71 | 79 |
|
72 | 80 | /** |
|
77 | 85 | * @return Bottle |
78 | 86 | */ |
79 | 87 | var constant = function constant(name, value) { |
80 | | - var parts = name.split('.'); |
| 88 | + var parts = name.split(DELIMITER); |
81 | 89 | name = parts.pop(); |
82 | 90 | defineConstant.call(parts.reduce(setValueObject, this.container), name, value); |
83 | 91 | return this; |
|
101 | 109 | */ |
102 | 110 | var decorator = function decorator(fullname, func) { |
103 | 111 | var parts, name; |
104 | | - if (typeof fullname === 'function') { |
| 112 | + if (typeof fullname === FUNCTION_TYPE) { |
105 | 113 | func = fullname; |
106 | | - fullname = '__global__'; |
| 114 | + fullname = GLOBAL_NAME; |
107 | 115 | } |
108 | 116 |
|
109 | | - parts = fullname.split('.'); |
| 117 | + parts = fullname.split(DELIMITER); |
110 | 118 | name = parts.shift(); |
111 | 119 | if (parts.length) { |
112 | | - getNestedBottle.call(this, name).decorator(parts.join('.'), func); |
| 120 | + getNestedBottle.call(this, name).decorator(parts.join(DELIMITER), func); |
113 | 121 | } else { |
114 | 122 | if (!this.decorators[name]) { |
115 | 123 | this.decorators[name] = []; |
|
234 | 242 | */ |
235 | 243 | var middleware = function middleware(fullname, func) { |
236 | 244 | var parts, name; |
237 | | - if (typeof fullname === 'function') { |
| 245 | + if (typeof fullname === FUNCTION_TYPE) { |
238 | 246 | func = fullname; |
239 | | - fullname = '__global__'; |
| 247 | + fullname = GLOBAL_NAME; |
240 | 248 | } |
241 | 249 |
|
242 | | - parts = fullname.split('.'); |
| 250 | + parts = fullname.split(DELIMITER); |
243 | 251 | name = parts.shift(); |
244 | 252 | if (parts.length) { |
245 | | - getNestedBottle.call(this, name).middleware(parts.join('.'), func); |
| 253 | + getNestedBottle.call(this, name).middleware(parts.join(DELIMITER), func); |
246 | 254 | } else { |
247 | 255 | if (!this.middlewares[name]) { |
248 | 256 | this.middlewares[name] = []; |
|
270 | 278 | */ |
271 | 279 | var pop = function pop(name) { |
272 | 280 | var instance; |
273 | | - if (typeof name === 'string') { |
| 281 | + if (typeof name === STRING_TYPE) { |
274 | 282 | instance = bottles[name]; |
275 | 283 | if (!instance) { |
276 | 284 | bottles[name] = instance = new Bottle(); |
|
285 | 293 | * Clear all named bottles. |
286 | 294 | */ |
287 | 295 | var clear = function clear(name) { |
288 | | - if (typeof name === 'string') { |
| 296 | + if (typeof name === STRING_TYPE) { |
289 | 297 | delete bottles[name]; |
290 | 298 | } else { |
291 | 299 | bottles = {}; |
|
312 | 320 | */ |
313 | 321 | var provider = function provider(fullname, Provider) { |
314 | 322 | var parts, name; |
315 | | - parts = fullname.split('.'); |
316 | | - if (this.providerMap[fullname] && parts.length === 1 && !this.container[fullname + 'Provider']) { |
| 323 | + parts = fullname.split(DELIMITER); |
| 324 | + if (this.providerMap[fullname] && parts.length === 1 && !this.container[fullname + PROVIDER_SUFFIX]) { |
317 | 325 | return console.error(fullname + ' provider already instantiated.'); |
318 | 326 | } |
319 | 327 | this.originalProviders[fullname] = Provider; |
|
322 | 330 | name = parts.shift(); |
323 | 331 |
|
324 | 332 | if (parts.length) { |
325 | | - getNestedBottle.call(this, name).provider(parts.join('.'), Provider); |
| 333 | + getNestedBottle.call(this, name).provider(parts.join(DELIMITER), Provider); |
326 | 334 | return this; |
327 | 335 | } |
328 | 336 | return createProvider.call(this, name, Provider); |
|
351 | 359 | container = this.container; |
352 | 360 | decorators = this.decorators; |
353 | 361 | middlewares = this.middlewares; |
354 | | - providerName = name + 'Provider'; |
| 362 | + providerName = name + PROVIDER_SUFFIX; |
355 | 363 |
|
356 | 364 | properties = Object.create(null); |
357 | 365 | properties[providerName] = { |
|
416 | 424 | var removeProviderMap = function resetProvider(name) { |
417 | 425 | delete this.providerMap[name]; |
418 | 426 | delete this.container[name]; |
419 | | - delete this.container[name + 'Provider']; |
| 427 | + delete this.container[name + PROVIDER_SUFFIX]; |
420 | 428 | }; |
421 | 429 |
|
422 | 430 | /** |
|
427 | 435 | var resetProviders = function resetProviders() { |
428 | 436 | var providers = this.originalProviders; |
429 | 437 | Object.keys(this.originalProviders).forEach(function resetPrvider(provider) { |
430 | | - var parts = provider.split('.'); |
| 438 | + var parts = provider.split(DELIMITER); |
431 | 439 | if (parts.length > 1) { |
432 | 440 | parts.forEach(removeProviderMap, getNestedBottle.call(this, parts[0])); |
433 | 441 | } |
|
452 | 460 | }; |
453 | 461 |
|
454 | 462 | /** |
455 | | - * Register a service inside a generic factory. |
| 463 | + * Register a function service |
| 464 | + */ |
| 465 | + var serviceFactory = function serviceFactory(name, factoryService) { |
| 466 | + return createService.apply(this, [name, factoryService, false].concat(slice.call(arguments, 2))); |
| 467 | + }; |
| 468 | + |
| 469 | + /** |
| 470 | + * Register a class service |
456 | 471 | * |
457 | 472 | * @param String name |
458 | 473 | * @param Function Service |
459 | 474 | * @return Bottle |
460 | 475 | */ |
461 | 476 | var service = function service(name, Service) { |
462 | | - var deps = arguments.length > 2 ? slice.call(arguments, 2) : null; |
| 477 | + return createService.apply(this, [name, Service, true].concat(slice.call(arguments, 2))); |
| 478 | + }; |
| 479 | + |
| 480 | + /** |
| 481 | + * Private helper for creating service and service factories. |
| 482 | + * |
| 483 | + * @param String name |
| 484 | + * @param Function Service |
| 485 | + * @return Bottle |
| 486 | + */ |
| 487 | + var createService = function createService(name, Service, isClass) { |
| 488 | + var deps = arguments.length > 3 ? slice.call(arguments, 3) : []; |
463 | 489 | var bottle = this; |
464 | 490 | return factory.call(this, name, function GenericFactory() { |
465 | | - var ServiceCopy = Service; |
466 | | - if (deps) { |
467 | | - var args = deps.map(getNestedService, bottle.container); |
468 | | - args.unshift(Service); |
469 | | - ServiceCopy = Service.bind.apply(Service, args); |
| 491 | + var serviceFactory = Service; // alias for jshint |
| 492 | + var args = deps.map(getNestedService, bottle.container); |
| 493 | + |
| 494 | + if (!isClass) { |
| 495 | + return serviceFactory.apply(null, args); |
470 | 496 | } |
471 | | - return new ServiceCopy(); |
| 497 | + return new (Service.bind.apply(Service, [null].concat(args)))(); |
472 | 498 | }); |
473 | 499 | }; |
474 | 500 |
|
|
481 | 507 | */ |
482 | 508 | var value = function value(name, val) { |
483 | 509 | var parts; |
484 | | - parts = name.split('.'); |
| 510 | + parts = name.split(DELIMITER); |
485 | 511 | name = parts.pop(); |
486 | 512 | defineValue.call(parts.reduce(setValueObject, this.container), name, val); |
487 | 513 | return this; |
|
562 | 588 | register : register, |
563 | 589 | resolve : resolve, |
564 | 590 | service : service, |
| 591 | + serviceFactory : serviceFactory, |
565 | 592 | value : value |
566 | 593 | }; |
567 | 594 |
|
|
631 | 658 | /** |
632 | 659 | * Export |
633 | 660 | */ |
634 | | - if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { |
| 661 | + if (typeof define === FUNCTION_TYPE && typeof define.amd === 'object' && define.amd) { |
635 | 662 | root.Bottle = Bottle; |
636 | 663 | define(function() { return Bottle; }); |
637 | 664 | } else if (freeExports && freeModule) { |
|
0 commit comments