-
Notifications
You must be signed in to change notification settings - Fork 5
Space.Injector
Space comes with a very lightweight dependency injection system. It tries to keep your code as clean as possible and doesn't force you to wrap your functions with library calls.
If an object needs some other code during runtime, it simply declares its dependency:
var dependendObject = {
dependencies: {
lib: 'OtherCode'
},
sayHello: function() {
this.lib.sayHello();
}
};
Now dependendObject
declares very explicitly that it needs OtherCode
which it will access via this.lib
later on. But where should OtherCode
come from?
This is where the Space.Injector
helps out:
var library = {
sayHello: function() {
console.log('hello!');
}
};
var injector = new Space.Injector();
// maps the string identifier 'OtherCode' to the library object
injector.map('OtherCode').to(library);
// injects all dependencies into the dependent object
injector.injectInto(dependendObject);
dependendObject.sayHello(); // logs: 'hello!'
Of course, this also works with Javascript constructors and prototypes:
var MyClass = function() {};
MyClass.prototype.dependencies = {
lib: 'OtherCode'
};
MyClass.prototype.sayHello = function() {
this.lib.sayHello()
};
var instance = new MyClass();
injector.injectInto(instance);
instance.sayHello(); // logs: 'hello!'
Providers are simple classes that encapsulate the logic of how to provide a requested value during dependency injection. There are many ways to deliver something: think about static values, singletons, return values from functions, creating new class instances for each request etc.
In the examples above we already used one provider: to
, which simply maps
a string identifier to the given value. The cool thing is: there many more by
default and you can add your own!
Space.Injector
comes with several default providers:
var injector = new Space.Injector();
// ===== STATIC VALUES =====
// Simply provides the value as-is
injector.map('value').to('test');
injector.map('value').toStaticValue({ some: 'api' });
injector.map('value').asStaticValue(); // only works with strings
// ===== CLASS INSTANCES =====
// Creates a new instance for every injection
injector.map('TestClass').toClass(Space.Object.extend());
injector.map('TestClass').toInstancesOf(Space.Object.extend());
// ===== SINGLETONS =====
// Creates a single instance and always returns the same
injector.map('TestClass').toSingleton(Space.Object.extend());
It's really easy to add your own providers:
var injector = new Space.Injector();
var LoremIpsumProvider = Space.Object.extend({
provide: function() {
return externalAPI.generateLoremIpsum();
}
});
injector.addProvider('toLoremIpsum', LoremIpsumProvider);
// now you can use it:
injector.map('lorem').toLoremIpsum();