Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/matejchalk/provide-inject
Dependency injection made simple
https://github.com/matejchalk/provide-inject
dependency-injection
Last synced: 2 months ago
JSON representation
Dependency injection made simple
- Host: GitHub
- URL: https://github.com/matejchalk/provide-inject
- Owner: matejchalk
- License: mit
- Created: 2024-05-19T08:23:37.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2024-09-30T13:18:08.000Z (3 months ago)
- Last Synced: 2024-10-12T07:34:20.263Z (2 months ago)
- Topics: dependency-injection
- Language: TypeScript
- Homepage:
- Size: 234 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# provide-inject
[![npm](https://img.shields.io/npm/v/provide-inject.svg)](https://www.npmjs.com/package/provide-inject)
[![CI](https://github.com/matejchalk/provide-inject/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/matejchalk/provide-inject/actions/workflows/ci.yml?query=branch%3Amain)
[![codecov](https://codecov.io/github/matejchalk/provide-inject/graph/badge.svg?token=HQ73M0I4WR)](https://codecov.io/github/matejchalk/provide-inject)💉 **Dependency injection** made simple.
## Features
- 🤓 nice and simple API - `provide` it, then `inject` it
- 🔌 framework-agnostic, runtime-agnostic
- 👣 lightweight, zero dependencies
- 🏭 supports classes, factory functions and arbitrary values
- 🥱 lazy initialization, `inject` may be called at any time
- 🌲 tree-shakeable providers
- ♻️ detects circular dependencies
- 🛡️ checks and infers provider types## Installation
Install in the usual way with your package manager. E.g. for NPM:
```sh
npm install provide-inject
```## Usage
The basic idea is you `provide` an `InjectionToken`, so that you can later `inject` it.
A simple example is providing some global value:
```ts
import { provide, inject, InjectionToken } from 'provide-inject';// create a dependency injection token with a type and description
const DB_URI_TOKEN = new InjectionToken('DB_URI');// provide a value during startup
provide({ token: DB_URI_TOKEN, useValue: 'mongodb://localhost:27017' });// access the provided value at some later point
const uri = inject(DB_URI_TOKEN);
```Classes can be used in place of injection tokens as a handy shorthand:
```ts
class Logger {
reportError(error: unknown) {
// ... some implementation ...
}
}provide(Logger);
class UserService {
readonly logger = inject(Logger);signOut() {
try {
// ... some implementation ...
} catch (error) {
logger.reportError(error);
}
}
}
```Alternatively, using an interface as the injection token makes for looser coupling:
```ts
interface ILogger {
reportError(error: unknown): void;
}const LOGGER_TOKEN = new InjectionToken('LOGGER');
class Logger implements ILogger {
reportError(error: unknown) {
// ... some implementation ...
}
}provide({ token: LOGGER_TOKEN, useClass: Logger });
class UserService {
readonly logger = inject(LOGGER_TOKEN);signOut() {
try {
// ... some implementation ...
} catch (error) {
logger.reportError(error);
}
}
}
```A non-OOP approach would be to use a factory function:
```ts
type Logger = {
reportError(error: unknown): void;
};function createLogger(): Logger {
return {
reportError(error) {
// ... some implementation ...
},
};
}const LOGGER_TOKEN = new InjectionToken('LOGGER');
provide({ token: LOGGER_TOKEN, useFactory: createLogger });
function createUserService() {
const logger = inject(LOGGER_TOKEN);return {
signOut() {
try {
// ... some implementation ...
} catch (error) {
logger.reportError(error);
}
},
};
}
```