DI
The DI package is a kernel that uses dependency injection pattern to manage a dependency object. This kernel has the DIHelper to expose its API.
DI helper
The DIHelper assists in the construction and creation of business instances in a plugin.
This Automatic Dependency Injection helper uses the concept of dio: dependency injection object. It is a special Javascript object that allows you to access the values of objects defined in the diHelper. Instances defined as value are directly accessible, but instances defined with factories or classes are created under demand, that means that the first time that the getter is executed for a given property, it invokes the factory or instantiates the class.
All instances are singletons, that means that for a given property name there will be only one single instance. If it has a factory, the factory is executed once (or zero if not accessed), and, if it has a class, the class is instantiated once (or zero if not accessed), regardless the number of times that the getter is executed.
Factories and class constructors always receive one single argument that is the dio. It allows to recover other instances needed for the creation of the current instance. It is recommended to use object destructuring in the function parameters in order to improve readability.
You can redefine dio properties with new factories, classes, or values, unless you have already instantiated it. Once you instantiate a given property, you cannot redefine it.
Some operations (invoke and instantiate) allows locals. Locals are values also injected to the current factory or constructor but they might be not defined. Locals can also overwrite any property previously defined, including the case in which it was previously instantiated. Locals are valid only during the current instantiation; other nested or required instantiations do not have access to them.
See with-factory for more information.
Example
// Define a service class
class MyService {
doStuff() { ... }
}
// Define something to do with the service
class MyConsumer {
constructor({ myService }) {
this._myService = myService;
}
letsDoStuff() {
this._myService.doStuff();
}
}
// Define instances at plugin
class MyPlugin implements Plugin {
constructor({ diHelper }) {
this._diHelper = diHelper;
}
onInit() {
diHelper.useClass('myService', MyService);
var aConsumer = diHelper.instantiate(MyConsumer);
aConsumer.letsDoStuff();
}
}
instantiate
Creates a new instance of the specified Type previously injecting required values.
The created object receives in the constructor the dio that allows it to get instances of defined values, factories, and classes and also those values present in locals, which take priority in case of conflict.
Usage
instantiate(Type: Function, locals: Object): Object
-
Type Function
The constructor of the object to instantiate.
-
locals Object
Optional injectable values.
Returns
-
Object
The instance of Type.
Example
class MyAction {
constructor({ myService, items }) {
this._myService = myService;
this._items = items;
}
doAction() {
this._items.forEach((item) => this._myService.doStuff(item));
}
}
const myAction = diHelper.instantiate(MyAction, {
items: [1, 2, 3, 4, 5],
});
myAction.doAction();
invoke
Invokes a function injecting values and returns its result.
The function receives in the constructor a special object that allows it to get instances of defined values, factories, and classes and also those values present in locals, which take priority in case of conflict.
Usage
invoke(fn: Function, locals: Object): Object
-
fn Function
The function to execute.
-
locals Object
Optional injectable values.
Returns
-
Object
The result of the invoked function.
Example
function transformItems({ myService, items }) {
return this._items.map((item) => this._myService.transform(item));
}
const transformedItems = diHelper.invoke(transformItems, {
items: [1, 2, 3, 4, 5],
});
console.log(transformedItems);
useClass
Defined a Class as constructor for the value of the given property name of the dio.
The first time that the property is received from the dio, it creates a new instance of the class and sets the dio as an argument of the constructor.
Note: There is a mechanism of protection that returns an alternative instance instead of the original which hides properties that starts with underscore and freezes the object interface.
Usage
useClass((name: string), (Class: Function));
-
name String
Name of the property to recover the instance.
-
Class Function
Constructor of the class to instance.
useClasses
Allows configuration of multiple property/constructor at once.
It is equivalent to call useClass(key, classes[key]) for each key in classes.
Usage
useClasses((classes: Object));
-
classes Object
A string-constructor pairs object.
useFactory
Defined a function as a factory for the value of the given property name of the dio.
The first time that the property is retrieved from the dio, it invokes the factory with dio as an argument and saves the result as value to inject.
Note: There is a mechanism of protection that if the resulting result is an object, it returns an alternative instance instead of the original which hides properties that starts with underscore and freezes the object interface.
Usage
useFactory((name: string), (aFactory: Function));
-
name String
Name of the property to recover the instance.
-
aFactory Function
Constructor of the class to instance.
useFactories
Allows configuration of multiple property/factory at once.
It is equivalent to call useFactory(key, factories[key]) for each key in factories.
Usage
useFactory((name: string), (aFactory: Function));
-
factories Object
A string-factory pairs object.
useValue
Defined a value of the given property name of the dio.
Note: There is a mechanism of protection that if the value is an object, it returns an alternative instance instead of the original which hides properties that starts with underscore and freezes the object interface.
Usage
useValue((name: string), (value: any));
-
name String
Name of the property to recover the instance.
-
value any
Value to inject.
useValues
Allows configuration of multiple property/value at once.
It is equivalent to call useValue(key, values[key]) for each key in values.
Usage
useValue((name: string), (value: any));
-
values Object
A string-value pairs object.
get
Gets a defined value directly.
Usage
get(name: string): any
-
name String
Name for the symbol to get.
Returns
-
any
The instance of the given symbol or undefined if it was not defined.

index.js
export default class {
constructor({ diHelper }) {
this._diHelper = diHelper;
diHelper.useValue('name', 'Dave');
}
onInit() {
const uiHelper = this._diHelper.get('uiHelper');
const name = this._diHelper.get('name');
uiHelper.putComponent('Example', () => `Hi ${name}.`);
}
}
spec.js
import React from 'react';
import { mount } from 'enzyme';
import { Kernel } from '@orion/core';
import { uiKernel } from '@orion/ui';
import Plugin from './index.js';
test('It displays "Hi Dave."', () => {
const kernel = new Kernel('test', [uiKernel]);
const POSComponent = kernel.get('POSComponent');
const pluginsManager = kernel.get('pluginsManager');
pluginsManager.addPlugin({ name: 'plugin' }, () => Plugin);
const wrapper = mount(<POSComponent componentName="Example" />);
expect(wrapper.text()).toBe('Hi Dave.');
});