Awesome
🥃 Brandi
Brandi is a dependency injection container powered by TypeScript.
- Framework agnostic. Can work with any UI or server framework.
- Lightweight and Effective. It is tiny and designed for maximum performance.
- Strongly typed. TypeScript support out of box.
- Decorators free. Does not require additional parameters in
tsconfig.json
andReflect
polyfill.
Packages
The Brandi packages are available for use with a module bundler or in a Node application.
The Brandi source code is written in TypeScript but we precompile both CommonJS and ESModule builds to ES2018.
Additionally, we provide builds precompiled to ESNext by esnext
, esnext:main
and esnext:module
fields.
TypeScript type definitions are included in the library and do not need to be installed additionally.
Brandi
The core library.
# NPM
npm install brandi
# Yarn
yarn add brandi
Brandi-React
The React bindings layer. It lets your React components get dependencies from Brandi containers.
Brandi-React requires React 16.8 or later. You'll also need to install Brandi.
# NPM
npm install brandi-react
# Yarn
yarn add brandi-react
No Dependencies
Brandi has no dependencies, but requires the following globals in order to work:
Symbol
WeakMap
Production
By default, Brandi will be in development mode. The development mode includes warnings about common mistakes
and capture()/restore()
Container
methods.
Don't forget to set process.env.NODE_ENV
to production
when deploying your application.
Documentation
You can find the Brandi documentation on the website.
The documentation is divided into several sections:
- Getting Started
- Reference
- Brandi-React
- Examples
Examples
Here are just basic examples.
<!-- More examples can be found in the documentation in the [Examples](https://brandi.js.org/examples) section. -->Getting Instance
Binding types and scopes are detailed in Binding Types and Binding Scopes sections of the documentation.
<!-- prettier-ignore-start -->import { Container, token } from 'brandi';
class ApiService {}
const TOKENS = {
/* ↓ Creates a typed token. */
apiService: token<ApiService>('apiService'),
};
const container = new Container();
container
.bind(TOKENS.apiService)
.toInstance(ApiService) /* ← Binds the token to an instance */
.inTransientScope(); /* ← in transient scope. */
/* ↓ Gets the instance from the container. */
const apiService = container.get(TOKENS.apiService);
expect(apiService).toBeInstanceOf(ApiService);
<!-- prettier-ignore-end -->
Snapshoting
<!-- prettier-ignore-start -->import { Container, token } from 'brandi';
const TOKENS = {
apiKey: token<string>('API Key'),
};
const container = new Container();
container
.bind(TOKENS.apiKey)
.toConstant('#key9428'); /* ← Binds the token to some string. */
/* ↓ Captures (snapshots) the current container state. */
container.capture();
container
.bind(TOKENS.apiKey)
.toConstant('#testKey'); /* ← Binds the same token to another value. */
/* For example, this can be used in testing. */
const testKey = container.get(TOKENS.apiKey);
/* ↓ Restores the captured container state. */
container.restore();
const originalKey = container.get(TOKENS.apiKey);
expect(testKey).toBe('#testKey');
expect(originalKey).toBe('#key9428');
<!-- prettier-ignore-end -->
Other Container
methods are detailed
in Container section of the documentation.
Hierarchical Containers
Hierarchical containers are detailed in Hierarchical Containers section of the documentation.
import { Container, token } from 'brandi';
class ApiService {}
const TOKENS = {
apiService: token<ApiService>('apiService'),
};
const parentContainer = new Container();
parentContainer
.bind(TOKENS.apiService)
.toInstance(ApiService)
.inTransientScope();
/* ↓ Creates a container with the parent. */
const childContainer = new Container().extend(parentContainer);
/** ↓ That container can't satisfy the getting request,
* it passes it along to its parent container.
* The intsance will be gotten from the parent container.
*/
const apiService = childContainer.get(TOKENS.apiService);
expect(apiService).toBeInstanceOf(ApiService);