UNPKG

4.84 kBJavaScriptView Raw
1'use strict'
2
3var mod$0 = require('./signals');var ACQUIRE = mod$0.ACQUIRE;var RELEASE = mod$0.RELEASE;var DISPOSE = mod$0.DISPOSE;
4var mod$1 = require('./constants');var CONTAINER_ALIAS = mod$1.CONTAINER_ALIAS;var CONTEXT_ALIAS = mod$1.CONTEXT_ALIAS;var CHILD_ALIAS = mod$1.CHILD_ALIAS;
5var VALUE = require('./options').VALUE;
6var mod$2 = require('./utils');var generateMask = mod$2.generateMask;var noop = mod$2.noop;var isEagerSingleton = mod$2.isEagerSingleton;
7var resolvers = require('./resolvers');
8var createContext = require('./createContext');
9
10
11
12 function Container(conf, logger, mappings, signalRelease) {
13 var context
14
15 if (typeof conf !== 'function') {
16 throw new Error('Invalid container creation, missing contribution function')
17 }
18
19 this.$Container_mappings = mappings || {}
20 this.$Container_resolvers = resolvers
21 this.$Container_logger = logger
22 this.$Container_resolving = {}
23 this.$Container_pending = []
24 this.$Container_children = {}
25 this.$Container_signalRelease = signalRelease || noop
26
27 this.$Container_bind(CONTAINER_ALIAS, this, VALUE, [])
28 context = this.$Container_context = createContext(this.$Container_bind.bind(this))
29 this.$Container_bind(CONTEXT_ALIAS, context, VALUE, [])
30 conf(context)
31 context.flush()
32 this.$Container_unbind(CONTEXT_ALIAS)
33 }
34
35 Container.prototype.get=function(alias, transients) {
36 return this.$Container_logger.log(("resolving '" + alias + "'"), function() {
37 if (this.$Container_resolving[alias]) { throw new Error(("Circular dependency detected while resolving '" + alias + "'")) }
38 if (!(alias in this.$Container_mappings)) { throw new Error(("'" + alias + "' is not available. Has it ever been registered?.")) }
39
40 this.$Container_resolving[alias] = true
41 try {
42 return this.$Container_mappings[alias](ACQUIRE)
43 } catch(err) {
44 err.message = ("Failed while resolving '" + alias + "' due to:\n\t" + err.message)
45 throw err
46 } finally {
47 this.$Container_resolving[alias] = false
48 }
49 }.bind(this))
50 };
51
52 Container.prototype.using=function(transientsDeps) {
53 return {
54 get: function(alias) {
55 var context = this.$Container_context
56 var dep
57
58 for (dep in transientsDeps) {
59 context.map(dep).to(transientsDeps[dep]).as(VALUE)
60 }
61 context.flush()
62 this.get(alias)
63 for (dep in transientsDeps) {
64 this.$Container_unbind(dep)
65 }
66 }.bind(this)
67 }
68 };
69
70 Container.prototype.release=function(alias) {
71 try {
72 this.$Container_mappings[alias](RELEASE)
73 } catch(err) {
74 err.message = ("Failed while releasing '" + alias + "' due to:\n\t" + err.message)
75 throw err
76 }
77 };
78
79 Container.prototype.createChild=function(conf) {
80 var id = Object.keys(this.$Container_children).length + 1
81 var child = new Container(conf, this.$Container_logger, Object.create(this.$Container_mappings), this.$Container_releaseChild.bind(this, id))
82
83 this.$Container_children[id] = child
84 return child
85 };
86
87 Container.prototype.dispose=function() {
88 this.$Container_disposeChildren()
89 this.$Container_disposeInstances()
90 this.$Container_signalRelease()
91 this.$Container_signalRelease = noop
92 };
93
94 Container.prototype.$Container_disposeChildren=function() {
95 var children = this.$Container_children
96 var id
97
98 for (id in children) {
99 /* istanbul ignore else */
100 if (children.hasOwnProperty(id)) {
101 children[id].dispose()
102 this.$Container_releaseChild(id)
103 }
104 }
105 };
106
107 Container.prototype.$Container_releaseChild=function(id) {
108 delete this.$Container_children[id]
109 };
110
111 Container.prototype.$Container_disposeInstances=function() {
112 var mappings = this.$Container_mappings
113 var alias
114
115 for (alias in mappings) {
116 /* istanbul ignore else */
117 if (mappings.hasOwnProperty(alias)) {
118 try {
119 mappings[alias](DISPOSE)
120 } catch(err) {
121 err.message = ("Failed while disposing '" + alias + "' due to:\n\t" + err.message)
122 throw err
123 }
124 delete mappings[alias]
125 }
126 }
127 };
128
129 Container.prototype.$Container_bind=function(alias, value, type, deps) {
130 if ( !(type in this.$Container_resolvers) ) {
131 throw new Error('Invalid flags combination. See documentation for valid flags combinations.')
132 }
133 this.$Container_mappings[alias] = this.$Container_resolvers[type].call(null, value, this.$Container_resolve.bind(this, deps), this.$Container_release.bind(this, deps))
134 if (isEagerSingleton(type)) {
135 this.get(alias)
136 }
137 };
138
139 Container.prototype.$Container_unbind=function(alias) {
140 this.$Container_mappings[alias](DISPOSE)
141 delete this.$Container_mappings[alias]
142 };
143
144 Container.prototype.$Container_release=function(deps) {
145 return deps.forEach(function(dep) {
146 this.release(dep)
147 }.bind(this))
148 };
149
150 Container.prototype.$Container_resolve=function(deps) {
151 return deps.map(function(dep) {
152 return this.get(dep)
153 }.bind(this))
154 };
155
156
157module.exports = Container
\No newline at end of file