@rocketmakers/ioc
v0.3.6
Published
## Introduction This package provides helper methods for inversify (https://inversify.io/) to: 1. simplify registering classes, functions and constants. 1. simplify resolving classes, functions and constants. 1. provide function curry facilities - resolvi
Downloads
7,373
Keywords
Readme
Rocketmakers IoC
Introduction
This package provides helper methods for inversify (https://inversify.io/) to:
- simplify registering classes, functions and constants.
- simplify resolving classes, functions and constants.
- provide function curry facilities - resolving function parameters from the IoC container.
Typing the Container
You should first create a type that describes your Container items, then create a containerRegister
to help you to register those types.
Application
service/admin.ts
export class AdminService {
doSomething(value: number) {
return Math.round(value);
}
}
controller/admin.ts
import { AdminService } from '../service/admin';
export class AdminController {
constructor(private adminService: AdminService) {}
}
service/external-api.ts
import { fetchUserData, IUser } from './external';
// NOTE: we want the apiKey param to be provided (curried) from the container - so we never need to explicitly pass this when consuming this function!
export function getExternalUserData(apiKey: string, id: number): IUser {
return fetchUserData(apiKey, id);
}
ioc/types.ts
import { Curried1, Curried2 } from '@rocketmakers/ioc';
// Application Types
import type { AdminController } from '../controller/admin';
import type { AdminService } from '../service/admin';
import type { getExternalUserData } from '../service/external-api';
/** Define the types registered within the container */
export type ControllerContainerTypes = {
id: number;
apiKey: string;
adminService: AdminService;
adminController: AdminController;
getExternalUserData: typeof getExternalUserData;
getExternalUserData1: Curried1<typeof getExternalUserData>;
getExternalUserData2: Curried2<typeof getExternalUserData>;
};
Registration (IoC Container Modules)
Building the container
ioc/register.ts
import { IContainer, register } from '@rocketmakers/ioc';
import { AdminController } from '../controller/admin';
import { AdminService } from '../service/admin';
import { getExternalUserData } from '../service/external-api';
import { ControllerContainerTypes } from './types';
export function makeContainer(): IContainer<ControllerContainerTypes> {
// Register all the keys of the 'ControllerContainerTypes'
return register<ControllerContainerTypes>({
id: b => b.constant(31313),
apiKey: b => b.constant('xyz...'),
adminService: b => b.class(AdminService, []),
adminController: b => b.class(AdminController, ['adminService']),
getExternalUserData: b => b.function(getExternalUserData),
getExternalUserData1: b => b.functionCurry(getExternalUserData, ['apiKey']),
getExternalUserData2: b => b.functionCurry(getExternalUserData, ['apiKey', 'id']),
});
}
ioc/register-with-prefix.ts
import { registerWithPrefix } from '@rocketmakers/ioc';
import { AdminController } from '../controller/admin';
import { AdminService } from '../service/admin';
import { getExternalUserData } from '../service/external-api';
import { ControllerContainerTypes } from './types';
export function makeContainerPrefixed<TPrefix extends string>(prefix: TPrefix, id: number, apiKey: string) {
// Register all the keys of the 'ControllerContainerTypes'
return registerWithPrefix<TPrefix, ControllerContainerTypes>('none', prefix, {
id: b => b.constant(id),
apiKey: b => b.constant(apiKey),
adminService: b => b.class(AdminService, []),
adminController: b => b.class(AdminController, ['adminService']),
getExternalUserData: b => b.function(getExternalUserData),
getExternalUserData1: b => b.functionCurry(getExternalUserData, ['apiKey']),
getExternalUserData2: b => b.functionCurry(getExternalUserData, ['apiKey', 'id']),
});
}
const v1 = makeContainerPrefixed('this-', 31313, 'xyz...');
v1.get('this-id');
v1.get('this-apiKey');
v1.get('this-adminService');
v1.get('this-adminController');
v1.get('this-getExternalUserData');
v1.get('this-getExternalUserData1');
v1.get('this-getExternalUserData2');
const v2 = makeContainerPrefixed('that-', 13131, 'abc...');
v2.get('that-id');
v2.get('that-apiKey');
v2.get('that-adminService');
v2.get('that-adminController');
v2.get('that-getExternalUserData');
v2.get('that-getExternalUserData1');
v2.get('that-getExternalUserData2');
Resolving with the container
import { makeContainer } from './ioc/register';
export function boot() {
// Register the container
const container = makeContainer();
// getExternalUserData1 has type "(id: number): IUser" as we curried out the apiKey param
const getExternalUserData1 = container.get('getExternalUserData1');
const userData = getExternalUserData1(23);
return userData;
}
boot();
Registration (Legacy)
Building the container
ioc/register.ts
import { containerFactory, containerRegister, containerRegisterFunctionResolver } from '@rocketmakers/ioc';
// Application Types
import { AdminController } from '../controller/admin';
import { AdminService } from '../service/admin';
import { getExternalUserData } from '../service/external-api';
import { ControllerContainerTypes } from './types';
/** @deprecated LEGACY: Create register helper */
export const register = containerRegister<ControllerContainerTypes>();
/** @deprecated LEGACY: Create function resolver */
export const functionResolver = containerRegisterFunctionResolver<ControllerContainerTypes>();
/** @deprecated LEGACY: Create register container */
export const container = containerFactory<ControllerContainerTypes>();
export function registerIoC(): void {
// Register all the keys of the 'ControllerContainerTypes'
register.constant('id', 31313);
register.constant('apiKey', 'xyz...');
register.class('adminService', AdminService).construct([]).inSingletonScope();
register.class('adminController', AdminController).construct(['adminService']).inSingletonScope();
register.function('getExternalUserData', getExternalUserData);
register.function('getExternalUserData1', functionResolver.curry1(getExternalUserData, 'apiKey'));
register.function('getExternalUserData2', functionResolver.curry2(getExternalUserData, 'apiKey', 'id'));
}
Resolving with the container
import { container, registerIoC } from './ioc/register-legacy';
export function boot() {
// Register the container
registerIoC();
// getExternalUserData has type "(id: number): IUser" as we curried out the apiKey param
const getExternalUserData1 = container.get('getExternalUserData1');
const userData = getExternalUserData1(23);
return userData;
}
boot();