peppermint-di
v2.0.2
Published
Dependency injection container for TypeScript and JavaScript
Downloads
13
Readme
peppermint-di
Dependency injection container for TypeScript and JavaScript.
Installation
yarn add peppermint-di
or
npm install --save peppermint-di
The gist
import { Container, injectable } from 'peppermint-di';
class SomeService {
// ...
}
@injectable
class SomeClass {
constructor(someService: SomeService) {
// ...
}
}
const container = new Container();
container.registerSingle(SomeService)
const myClass = container.get(SomeClass);
Table of Content
Credits
This project was originally based on this blog post by Yusuf Aytas as it appeared in this StackOverflow question.
The API is somewhat inspired by the excellent Simple Injector C# library.
Examples
TypeScript
Custom parameters
import { Container, injectable } from 'peppermint-di';
class SomeService {
public name = 'default name';
}
@injectable
class MyClass {
public myService: SomeService;
constructor(myService: SomeService) {
this.myService = myService;
}
}
const container = new Container();
const customDep = new SomeService();
customDep.name = 'custom name';
const customParameters = new Map([
[SomeService, customDep]
]);
const myClass = container.get(MyClass, { params: customParameters });
expect(myClass.myService).to.be.instanceOf(SomeService);
expect(myClass.myService.name).to.eql('custom name');
Interface registration
import { Container, i, injectable } from 'peppermint-di';
//
// the interface
//
interface ISomeService {
}
const ISomeService = Symbol('ISomeService');
//
// the concrete type
//
class ConcreteSomeService implements ISomeService {
}
//
// the class to resolve
//
@injectable
class MyClass {
public myService: ISomeService;
constructor(@i(ISomeService) myService: ISomeService) {
this.myService = myService;
}
}
//
// test
//
const container = new Container();
container.register(ISomeService, ConcreteSomeService);
const myClass = container.get(MyClass);
expect(myClass).to.be.instanceOf(MyClass);
expect(myClass.myService).to.be.instanceOf(ConcreteSomeService);
Instance initializers
import { Container, injectable } from 'peppermint-di';
class SomeService {
public someFeatureFlag = false;
}
const container = new Container();
container.registerSingle(SomeService)
container.registerInitializer(SomeService, serviceInstance => {
serviceInstance.someFeatureFlag = true;
});
const myService = container.get(SomeService);
expect(myService.someFeatureFlag).to.be.true;
JavaScript
Simple example
import { Container } from 'peppermint-di';
class SomeService {
// ...
}
class SomeClass {
constructor(someService) {
// ...
}
}
const container = new Container();
container.registerSingle('someService', SomeService);
const myClass = container.get(SomeClass);
Custom parameters
import { Container } from 'peppermint-di';
class SomeService {
constructor() {
this.name = 'default name';
}
}
class MyClass {
constructor(myService) {
this.myService = myService;
}
}
const container = new Container();
const customDep = new SomeService();
customDep.name = 'custom name';
const customParameters = new Map([
['myService', customDep]
]);
const myClass = container.get(MyClass, { params: customParameters });
expect(myClass.myService).to.be.instanceOf(SomeService);
expect(myClass.myService.name).to.eql('custom name');
API
You can find here a brief overview of the Container API.
For a more comprehensive review see the typing file.
You can also check out the library's unit tests as they contains examples for most use cases.
Container
Container key type:
type ContainerKey<T> = Constructor<T> | SimpleContainerKey;
type SimpleContainerKey = string | symbol;
Register a transient service.
Container.register<T>(key: Constructor<T>, type?: Constructor<T>): void;
Container.register<T>(key: SimpleContainerKey, type: Constructor<T>): void;
Container.registerFactory<T>(key: ContainerKey<T>, factory: Factory<T>): void;
Register a singleton service.
Container.registerSingle<T>(key: Constructor<T>, valueOrType?: T | Constructor<T>): void;
Container.registerSingle<T>(key: SimpleContainerKey, valueOrType: T | Constructor<T>): void;
Container.registerSingleFactory<T>(key: ContainerKey<T>, factory: Factory<T>): void;
Register an initializer.
type Initializer<T> = (instance: T) => void;
Container.registerInitializer<T>(key: ContainerKey<T>, initializer: Initializer<T>): void
Get an instance of T.
Container.get<T>(key: ContainerKey<T>, options?: ResolveOptions): T;
Resolve function arguments and call it.
Container.call(foo: Function, thisArg?: any, options?: ResolveOptions): any;
ResolveOptions
class ResolveOptions {
/**
* If set to 'true' will treat unregistered dependencies as optional
* parameters and set their value to undefined.
*
* Default value: false
*/
optionalParameters?: boolean;
/**
* Set to 'false' if you don't want the injector to automatically try to
* construct unregistered constructors.
*
* Default value: true
*/
constructUnregistered?: boolean;
/**
* Parameters specified here will be used directly instead of being resolved.
*/
params?: Map<ContainerKey<any>, any>;
}
Changelog
The change log can be found here.