Skip to content

Instantly share code, notes, and snippets.

@tusharmath
Created April 7, 2015 15:30
Show Gist options
  • Save tusharmath/92ec63540589e9107f13 to your computer and use it in GitHub Desktop.
Save tusharmath/92ec63540589e9107f13 to your computer and use it in GitHub Desktop.
Simple IOC pattern for Javascript
"use strict";
var should = require('chai').should();
var _bind = Function.prototype.bind;
var _each = function (arr, callback, ctx) {
for (var i = 0; i < arr.length; i++) {
callback.call(ctx, arr[i]);
}
};
var _find = function (arr, callback, ctx) {
var validItem = null;
_each(arr, function (i) {
if (callback.call(ctx, i)) {
validItem = i;
}
});
return validItem;
}
var _map = function (arr, callback, ctx) {
var temp = [];
_each(arr, function (i) {
temp.push(callback.call(ctx, i));
}, this);
return temp;
};
function Injector() {
this._singletons = [];
}
Injector.prototype.get = function (className) {
var instance;
if (className === Injector) {
return this;
}
if (className.$singleton) {
instance = _find(this._singletons, function (i) {
return i instanceof className;
});
}
if (instance) {
return instance
}
var instances = [];
if (className.$inject) {
instances = _map(className.$inject, function (className) {
return this.get(className);
}, this);
}
var ctor = function () {
className.apply(this, arguments);
};
ctor.prototype = className.prototype;
instances.unshift(null);
var _ctor = _bind.apply(ctor, instances);
instance = new _ctor();
if (className.$singleton) {
this._singletons.push(instance);
}
return instance;
};
// Test Cases
describe('Injector', function () {
beforeEach(function () {
this.mod = new Injector();
this.A = function A() {};
this.B = function B() {};
});
it('should exist', function () {
should.exist(Injector);
});
describe('get()', function () {
it('returns an instance of a class', function () {
this.mod.get(this.A).should.be.an.instanceOf(this.A);
});
it('returns an instance of a class with dependencies', function () {
var temp2 = function temp2(a, b) {
this.a = a;
this.b = b;
};
temp2.$inject = [this.A, this.B];
var x = this.mod.get(temp2);
x.a.should.be.an.instanceOf(this.A);
x.b.should.be.an.instanceOf(this.B);
});
it('returns an instance of a class', function () {
this.A.$singleton = true;
this.mod.get(this.A).should
.equal(this.mod.get(this.A));
});
it('returns itself when asked for', function () {
this.mod.get(Injector).should.equal(this.mod);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment