Skip to content
Dominik Guzei edited this page Jan 19, 2016 · 2 revisions

Introduction

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

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!

Default Providers

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());

Custom Providers

It's really easy to add your own providers:

Example: Lorem Ipsum

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();