Mercurial > pub > ImplabJs
diff src/implab/di/ActivationContext.js @ 0:fc2517695ee1
Initial commit, draft import of existing work
author | cin |
---|---|
date | Thu, 01 Jun 2017 13:20:03 +0300 |
parents | |
children | 00779cb63b12 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/implab/di/ActivationContext.js Thu Jun 01 13:20:03 2017 +0300 @@ -0,0 +1,139 @@ +define([ + "../declare", + "../safe", + "./Descriptor", + "./ValueDescriptor" + ], + + function (declare, safe, Descriptor, Value) { + var Context = declare(null, { + + _cache: null, + + _services: null, + + _stack: null, + + _visited: null, + + container: null, + + _trace: false, + + constructor: function (container, services, cache, visited) { + safe.argumentNotNull(container, "container"); + safe.argumentNotNull(services, "services"); + + this._visited = visited || {}; + this._stack = []; + this._cache = cache || {}; + this._services = services; + this.container = container; + }, + + getService: function (name, def) { + var d = this._services[name]; + + if (!d) + if (arguments.length > 1) + return def; + else + throw new Error("Service '" + name + "' not found"); + + return d.activate(this, name); + }, + + /** + * registers services local to the the activation context + * + * @name{string} the name of the service + * @service{string} the service descriptor to register + */ + register: function (name, service) { + safe.argumentNotEmptyString(name, "name"); + + if (!(service instanceof Descriptor)) + service = new Value(service, true); + this._services[name] = service; + }, + + clone: function () { + return new Context( + this.container, + safe.create(this._services), + this._cache, + this._visited + ); + + }, + + has: function (id) { + return id in this._cache; + }, + + get: function (id) { + return this._cache[id]; + }, + + store: function (id, value) { + return (this._cache[id] = value); + }, + + parse: function (data, name) { + var me = this; + if (safe.isPrimitive(data)) + return data; + + if (data instanceof Descriptor) { + return data.activate(this, name); + } else if (data instanceof Array) { + me.enter(name); + var v = data.map(function (x, i) { + return me.parse(x, "." + i); + }); + me.leave(); + return v; + } else { + me.enter(name); + var result = {}; + for (var p in data) + result[p] = me.parse(data[p], "." + p); + me.leave(); + return result; + } + }, + + visit: function (id) { + var count = this._visited[id] || 0; + this._visited[id] = count + 1; + return count; + }, + + getStack: function () { + return this._stack.slice().reverse(); + }, + + enter: function (name, d, localize) { + if (this._trace) + console.log("enter " + name + " " + (d || "") + + (localize ? " localize" : "")); + this._stack.push({ + name: name, + service: d, + scope: this._services + }); + if (localize) + this._services = safe.create(this._services); + }, + + leave: function () { + var ctx = this._stack.pop(); + this._services = ctx.scope; + + if (this._trace) + console.log("leave " + ctx.name + " " + (ctx.service || "")); + } + }); + + return Context; + }); \ No newline at end of file