Index

redi

starsdownloadslicensecoverage

redi (pronounced ‘ready’) is a dependency injection library for TypeScript (and JavaScript), along with a set of bindings for React.

💡

1.0 release is out! Read the announcement.

Highlights

  • Zero dependencies, lightweight and fast.
  • No emitDecoratorMetadata required, works in both TypeScript and JavaScript. esbuild friendly.
  • Written in TypeScript with type definitions included.
  • Runs on Node.js and browsers.
  • Feature-rich:
    • Injecting class instances { useClass: <ctor> }, primitive values { useValue: <value> }, factories { useFactory: <factoryFn> } and aliases { useExisting: <token> }.
    • Injecting interfaces with createIdentifier.
    • Lazy instantiation with { useClass: <ctor>, lazy: true }.
    • Async dependency with { useAsync: <Promise> }, getAsync and AsyncHook.
    • Optional and multi-injection with @Optional() and @Many().
    • Hierarchical injectors with @Self() and @SkipSelf().
  • Provide hooks to integrate with React useDependency(<token>).
  • Sufficiently tested with 100% code coverage.

Installation

Use your favorite package manager:

npm install @wendellhu/redi

Usage (TypeScript)

Enable experimental decorators in your tsconfig.json:

{
  "compilerOptions": {
+   "experimentalDecorators": true,
  }
}

Then you can use decorators to define dependencies:

import { Inject } from '@wendellhu/redi';
 
class AuthService {
  public getCurrentUserInfo(): UserInfo {}
}
 
class FileListService {
  constructor(@Inject(AuthService) private readonly authService: AuthService) {}
 
  public getUserFiles(): Promise<Files> {
    const currentUser = this.authService.getCurrentUserInfo();
  }
}

Register the services in an injector and retrieve them:

import { Injector } from '@wendellhu/redi';
 
const injector = new Injector([[AuthService], [FileListService]]);
injector.get(AuthService);

With React

Near the root of your React application, you can connect the dependencies to the React context using connectDependencies:

import { connectDependencies } from '@wendellhu/redi/react';
import React from 'react';
import { PlatformService } from './services/PlatformService';
 
const App = connectDependencies(() => {
  // ...
}, [[PlatformService]]);

In your child components, you can use the useDependency hook to access them:

import { useDependency } from '@wendellhu/redi';
import React from 'react';
import { PlatformService } from './services/PlatformService';
 
const MyComponent: React.FC = () => {
  const platformService = useDependency(PlatformService);
 
  // ...
};

Who is using?

Contributing

Please read the contributing guide for details on how to contribute to this project.

License

MIT. Copyright 2021-present Wenzhao Hu.