UNPKG

5.74 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.10.0
2var Container, ModuleNotFound, construct, getArguments, runFactory, throwNotFound;
3
4ModuleNotFound = require('./ModuleNotFound');
5
6getArguments = require('./get-arguments');
7
8construct = function(c, args) {
9 var F;
10 F = (function() {
11 function F() {
12 c.apply(this, args);
13 }
14
15 return F;
16
17 })();
18 F.prototype = c.prototype;
19 return new F();
20};
21
22runFactory = function(factory, args) {
23 return factory.apply(null, args);
24};
25
26throwNotFound = function(name, parent) {
27 throw new ModuleNotFound(name, parent);
28};
29
30module.exports = Container = (function() {
31 function Container(conf, _parents) {
32 if (conf == null) {
33 conf = {};
34 }
35 this._parents = _parents != null ? _parents : [];
36 this._modules = conf.modules || {};
37 this._registrations = {};
38 this._instances = {};
39 }
40
41 Container.prototype.factory = function(name, func) {
42 if (!(func instanceof Function)) {
43 throw new Error('A factory must be a function');
44 }
45 return this._register('factory', name, func);
46 };
47
48 Container.prototype.value = function(name, value) {
49 return this._register('value', name, value);
50 };
51
52 Container.prototype["class"] = function(name, constructor) {
53 if (!(constructor instanceof Function)) {
54 throw new TypeError('A constructor must be a function');
55 }
56 return this._register('class', name, constructor);
57 };
58
59 Container.prototype.get = function(name) {
60 var registeredAt;
61 if (!this.isRegistered(name)) {
62 throwNotFound(name);
63 }
64 registeredAt = this._registeredAt(name);
65 if (registeredAt === 'local') {
66 if (!this._isInstantiated(name)) {
67 this._instantiate(name);
68 }
69 return this._instances[name];
70 } else {
71 return this._parents[registeredAt].get(name);
72 }
73 };
74
75 Container.prototype._isInstantiated = function(name) {
76 return Object.keys(this._instances).indexOf(name) !== -1;
77 };
78
79 Container.prototype._registeredAt = function(name) {
80 var i, j, len, p, parentIndex, ref;
81 if (this._registrations[name] != null) {
82 return 'local';
83 } else {
84 ref = this._parents;
85 for (i = j = 0, len = ref.length; j < len; i = ++j) {
86 p = ref[i];
87 if (p._registeredAt(name) != null) {
88 parentIndex = i;
89 }
90 }
91 return parentIndex;
92 }
93 };
94
95 Container.prototype.isRegistered = function(name) {
96 return this._registeredAt(name) !== void 0;
97 };
98
99 Container.prototype.getRegistrations = function() {
100 var all, p;
101 if (this._parents.length === 0) {
102 return this._registrations;
103 }
104 all = (function() {
105 var j, len, ref, results;
106 ref = this._parents;
107 results = [];
108 for (j = 0, len = ref.length; j < len; j++) {
109 p = ref[j];
110 results.push(p.getRegistrations());
111 }
112 return results;
113 }).call(this);
114 all.push(this._registrations);
115 return all.reduce(function(acc, item) {
116 Object.keys(item).forEach(function(key) {
117 return acc[key] = item[key];
118 });
119 return acc;
120 }, {});
121 };
122
123 Container.prototype.getArguments = function(name) {
124 if (this._modules[name] != null) {
125 return this._modules[name];
126 } else {
127 return getArguments(this._registrations[name].value);
128 }
129 };
130
131 Container.prototype.loadAll = function() {
132 var j, len, p, ref;
133 ref = this._parents;
134 for (j = 0, len = ref.length; j < len; j++) {
135 p = ref[j];
136 p.loadAll();
137 }
138 return Object.keys(this._registrations).forEach((function(_this) {
139 return function(name) {
140 if (!_this._isInstantiated(name)) {
141 return _this._instantiate(name);
142 }
143 };
144 })(this));
145 };
146
147 Container.prototype.shutdown = function() {
148 var j, len, p, ref, results;
149 Object.keys(this._instances).forEach((function(_this) {
150 return function(key) {
151 var ref;
152 return (ref = _this._instances[key]) != null ? typeof ref.__amendShutdown === "function" ? ref.__amendShutdown() : void 0 : void 0;
153 };
154 })(this));
155 ref = this._parents;
156 results = [];
157 for (j = 0, len = ref.length; j < len; j++) {
158 p = ref[j];
159 results.push(p.shutdown());
160 }
161 return results;
162 };
163
164 Container.prototype._register = function(type, name, value) {
165 return this._registrations[name] = {
166 value: value,
167 type: type
168 };
169 };
170
171 Container.prototype._instantiate = function(name, parent) {
172 var instance, module, type, value;
173 module = this._registrations[name];
174 if (module == null) {
175 throwNotFound(name, parent);
176 }
177 type = module.type;
178 value = module.value;
179 instance = type === 'value' ? value : this._instantiateWithDependencies(name, value, type);
180 this._instances[name] = instance;
181 return instance;
182 };
183
184 Container.prototype._instantiateWithDependencies = function(name, value, type) {
185 var args, dependencies;
186 args = this.getArguments(name);
187 dependencies = args.map((function(_this) {
188 return function(depName) {
189 var registeredAt;
190 registeredAt = _this._registeredAt(depName);
191 if (registeredAt === 'local') {
192 if (_this._isInstantiated(depName)) {
193 return _this._instances[depName];
194 } else {
195 return _this._instantiate(depName, name);
196 }
197 } else if (registeredAt != null) {
198 return _this._parents[registeredAt].get(depName);
199 } else {
200 return throwNotFound(depName, name);
201 }
202 };
203 })(this));
204 if (type === 'factory') {
205 return runFactory(value, dependencies);
206 }
207 if (type === 'class') {
208 return construct(value, dependencies);
209 }
210 };
211
212 return Container;
213
214})();