88 lines
2.1 KiB
Markdown
88 lines
2.1 KiB
Markdown
# Dependency manager
|
|
|
|
This lib provides a simplistic dependency manager.
|
|
|
|
## Features
|
|
|
|
- Resolves dependencies only when they are needed
|
|
- Detects circular dependency
|
|
- Allows "module" registration (grouped dependencies)
|
|
|
|
## Basic usage
|
|
|
|
```typescript
|
|
import { DependencyManager } from 'dependency-manager/mod.ts'
|
|
|
|
// 1. Create a manager:
|
|
const manager = new DependencyManager();
|
|
|
|
// 2. Create a dependency:
|
|
const dependency = () => 'value';
|
|
|
|
// 3. Register the dependency:
|
|
manager.register(dependency);
|
|
|
|
// 4. Anywhere in your code, get the resolved dependency value:
|
|
const value = await manager.resolve(dependency);
|
|
```
|
|
|
|
## Providers
|
|
|
|
To register a dependency, we pass a function to the dependency manager.
|
|
This function is called a provider.
|
|
|
|
Providers are called when resolving the dependency for the first time.
|
|
They receive the dependency manager as parameter, and should return the dependency value.
|
|
|
|
Example of the registration of a dependency which provider uses another dependency:
|
|
|
|
```typescript
|
|
function dependency(manager: DependencyManager) {
|
|
const value = manager.resolve(otherDependency);
|
|
return `The value is: ${valueA}`;
|
|
}
|
|
manager.register(dependency);
|
|
manager.register(otherDependency);
|
|
```
|
|
|
|
## Typing
|
|
|
|
The reason we pass the provider to resolve a dependency is that it allow the `resolve` method to correctly type the returned value:
|
|
|
|
```typescript
|
|
const A = () => 'foo';
|
|
const B = () => 42;
|
|
const C = () => ({});
|
|
|
|
const a = manager.resolve(A); //< `a` is of type `string`
|
|
const b = manager.resolve(B); //< `b` is of type `number`
|
|
const c = manager.resolve(C); //< `c` is of type `object`
|
|
```
|
|
|
|
## Modules
|
|
|
|
It is possible to register many dependency at once by using "modules".
|
|
|
|
A module is an object whose values are dependencies or modules.
|
|
|
|
```typescript
|
|
const moduleA = {
|
|
dependencyB: () => 'b',
|
|
moduleC: {
|
|
dependencyD: () => 'd',
|
|
},
|
|
};
|
|
|
|
manager.register(moduleA);
|
|
|
|
const d = manager.resolve(moduleA.moduleC.dependencyD);
|
|
```
|
|
|
|
## Errors
|
|
|
|
The `register` method throw an error if:
|
|
- the dependency is already registred.
|
|
|
|
The `resolve` method throw an error if:
|
|
- the dependency is not registred.
|
|
- a circular dependency is detected |