Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ahzhezhe/dependency-injection-ts
https://github.com/ahzhezhe/dependency-injection-ts
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/ahzhezhe/dependency-injection-ts
- Owner: ahzhezhe
- License: isc
- Created: 2023-06-24T09:30:32.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-03-14T09:35:24.000Z (9 months ago)
- Last Synced: 2024-05-21T03:06:59.985Z (7 months ago)
- Language: TypeScript
- Size: 483 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# **dependency-injection-ts**
[![GitHub test](https://github.com/ahzhezhe/dependency-injection-ts/workflows/test/badge.svg?branch=master)](https://github.com/ahzhezhe/dependency-injection-ts)
[![GitHub issues](https://img.shields.io/github/issues/ahzhezhe/dependency-injection-ts)](https://github.com/ahzhezhe/dependency-injection-ts/issues)
[![GitHub license](https://img.shields.io/github/license/ahzhezhe/dependency-injection-ts)](https://github.com/ahzhezhe/dependency-injection-ts/blob/master/LICENSE)
## **What is dependency-injection-ts?**
dependency-injection-ts is a dependency injection library for TypeScript.It provides:
- Constructor parameters injection.
- Class, value & token injection.
- Singleton & transient injectable.
- Decorators for injectable classes and parameter injections.
# **tsconfig.json**
Make sure that these 2 options are set to true
```json
{
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
```
# **Injectable**
Injectable can be a class instance or any value.
# **Token**
A token will be resolved to an injectable during injection.A token can be a class, a string or a symbol.
# **Register an injectable class**
```typescript
@Injectable()
export class ClassA {
}// or
Container.register(ClassA);
```## **Scope**
```typescript
@Injectable({ scope: Scope.TRANSIENT })
export class ClassA {
}// or
Container.register(ClassA, { scope: Scope.TRANSIENT });
```Available scopes:
- `Singleton` - Class will only be instantiated once and resued throughout the container.
- `Transient` - Class will be instantiated everytime it is retrieved/injected from container.Default scope is singleton.
# **Register an injectable value**
```typescript
Container.register('A', { value: 'hello world' });
```
Token `'A'` will be resolved to string value `'hello world'`.
# **Register an injectable token alias**
```typescript
Container.register('B', { token: 'A' });
```
Token `'B'` will be resolved to whatever token `'A'` is registered as.That makes token `'B'` an alias of token `'A'`.
# **Register an injectable class alias**
```typescript
export class ParentClass {
}@Injectable({ token: ParentClass })
export class ClassA extends ParentClass {
}// or
Container.register(ParentClass, { class: ClassA });
```
Token `ParentClass` will be resolved to an instance of `ClassA` instead of `ParentClass` itself.
# **Register using decorator**
```typescript
@Register([
['A', { value: 'hello world' }]
['B', { token: 'A' }]
])
@Injectable()
export class ClassA {
}
```
# **Inject constructor parameters**
## **Auto injection**
```typescript
@Injectable()
export class ClassA {
}@Injectable()
export class ClassB {constructor(
readonly a: ClassA // will be injected with an instance of ClassA based on parameter type
) {}}
```## **Explicit injection**
```typescript
export class ParentClass {
}@Injectable()
export class ClassA extends ParentClass {
}@Injectable()
export class ClassB {constructor(
@Inject(ClassA) readonly a: ParentClass // will be injected with an instance of ClassA despite the parameter type is ParentClass
) {}}
```## **Token injection**
```typescript
Container.register('A', { value: 'hello world' });
Container.register('B', { token: 'A' });@Injectable()
export class ClassA {constructor(
@Inject('A') readonly a: string, // will be injected with string value 'hello world'
@Inject('B') readonly b: string // will be injected with token 'A', which resolved as string value 'hello world'
) {}}
```## **Array injection**
```typescript
Container.register('A', { value: 'hello' });
Container.register('A', { value: 'world' });export class ParentClass {
}@Injectable({ token: ParentClass })
export class ClassA extends ParentClass {
}@Injectable({ token: ParentClass })
export class ClassB extends ParentClass {
}@Injectable()
export class ClassC {constructor(
@InjectAll('A') readonly a: string[], // will be injected with string array ['hello', 'world']
@InjectAll(ParentClass) readonly b: ParentClass[], // will be injected with an array that contains instances of ClassA and ClassB
) {}}
```## **All kind of injections**
- `@Inject` or `@InjectOne` - inject exactly one injectable in the container, no injectable or more than one injectable will result in error.
- `@InjectOneOrNone` - inject exactly one injectable in the container, no injectable will result in `undefined`, more than one injectable will result in error.
- `@InjectAny` - inject the first registered injectable in the container, no injectable will result in error.
- `@InjectAnyOrNone` - inject the first registered injectable in the container, no injectable will result in `undefined`.
- `@InjectAll` - inject all and at least one injectable, no injectable will result in error.
- `@InjectAllOrNone` - inject all injectables, no injectable will result in empty array.
# **Transformer**
## **Transform during registration**
```typescript
Container.register('A', { value: 'hello' });
Container.register('B', { token: 'A', transformer: value => value + ' world' });@Injectable()
export class ClassA {constructor(
@Inject('B') readonly a: string, // will be injected with string value 'hello world'
) {}}
```## **Transform during injection**
```typescript
Container.register('A', { value: 'hello' });@Injectable()
export class ClassA {constructor(
@Inject('A', { transformer: value => value + ' world' }) readonly a: string, // will be injected with string value 'hello world'
) {}}
```## **Transform during both registration and injection**
```typescript
Container.register('A', { value: 'hello' });
Container.register('B', { token: 'A', transformer: value => value + ' 1' });@Injectable()
export class ClassA {constructor(
@Inject('B', { transformer: value => value + ' 2' }) readonly a: string, // will be injected with string value 'hello 1 2'
) {}}
```
## **Getting injectable from container**
```typescript
Container.register('A', { value: 'hello world' });@Injectable()
export class ClassA {private readonly val = Container.get('A'); // returns string value 'hello world'
}
const a = Container.get(ClassA); // returns an instance of ClassA
```