• Stars
    star
    191
  • Rank 202,877 (Top 4 %)
  • Language
    TypeScript
  • License
    ISC License
  • Created almost 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The dependency injection container powered by TypeScript.

πŸ₯ƒ 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 and Reflect 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.

License NPM Version Minzipped Size

# NPM
npm install brandi
# Yarn
yarn add brandi

Brandi-React

The React bindings layer. It lets your React components get dependencies from Brandi containers.

License NPM Version Minzipped Size

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:

Examples

Here are just basic examples.

Getting Instance

Binding types and scopes are detailed in Binding Types and Binding Scopes sections of the documentation.

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

Snapshoting

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

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