1 | class Injector
|
2 | constructor: (@binders...) ->
|
3 | @_singletons = {}
|
4 |
|
5 | getInstance: (cls, args...) ->
|
6 | for binder in @binders
|
7 | for binding in binder.bindings
|
8 | instance = @_resolve(cls, binding)
|
9 | if instance? then return instance
|
10 |
|
11 | unless cls.prototype? then throw Error('Could not resolve')
|
12 | @_createNew(cls, undefined, args...)
|
13 |
|
14 | _createNew: (cls, scope, args...) ->
|
15 | if cls is Injector then return this
|
16 | if @_singletons[cls] then return @_singletons[cls]
|
17 |
|
18 | ptype = ->
|
19 | ptype.prototype = cls.prototype
|
20 | instance = new ptype()
|
21 | @_injectFields(cls.prototype, instance)
|
22 | cls.apply(instance, args)
|
23 |
|
24 | if scope?.toUpperCase?() is 'SINGLETON' or cls.scope?.toUpperCase?() is 'SINGLETON'
|
25 | @_singletons[cls] = instance
|
26 |
|
27 | instance
|
28 |
|
29 | _resolve: (cls, binding) ->
|
30 | if binding.matches(cls)
|
31 | defaultFactory = =>
|
32 | @_createNew(binding.impl, binding.scope)
|
33 | binding.create(defaultFactory)
|
34 |
|
35 | _injectFields: (ptype, instance) ->
|
36 | for k, v of ptype
|
37 | if v? and v._requiresInjection_
|
38 | instance[k] = @getInstance(v.cls, v.args...)
|
39 |
|
40 | module.exports = Injector
|