provider is key
This commit is contained in:
78
readme.md
78
readme.md
@@ -5,66 +5,84 @@ This lib provides a simplistic dependency manager.
|
||||
## Features
|
||||
|
||||
- Resolves dependencies only when they are needed
|
||||
- Detect circular dependency
|
||||
- Accept any valid `Map` key as dependency identifier
|
||||
- Infer the dependency type from the dependency identifier if the later is a class
|
||||
- Detects circular dependency
|
||||
- Allows "module" registration (grouped dependencies)
|
||||
|
||||
## Usage
|
||||
|
||||
1. Create a manager:
|
||||
## Basic usage
|
||||
|
||||
```typescript
|
||||
import { DependencyManager } from 'dependency-manager/mod.ts'
|
||||
|
||||
const manager = new DependencyManager()
|
||||
```
|
||||
// 1. Create a manager:
|
||||
const manager = new DependencyManager();
|
||||
|
||||
2. Register dependencies by giving the manager an identifier and a provider:
|
||||
// 2. Create a dependency:
|
||||
const dependency = () => 'value';
|
||||
|
||||
```typescript
|
||||
manager.register('dependency-identifier', () => 'value');
|
||||
```
|
||||
// 3. Register the dependency:
|
||||
manager.register(dependency);
|
||||
|
||||
3. Get the dependency by giving the manager its identifier (always asynchrone):
|
||||
|
||||
```typescript
|
||||
const value = await manager.resolve('dependency-identifier');
|
||||
// 4. Anywhere in your code, get the resolved dependency value:
|
||||
const value = await manager.resolve(dependency);
|
||||
```
|
||||
|
||||
## Providers
|
||||
|
||||
Providers are functions that are called when resolving the dependency for the first time.
|
||||
They receive the dependency manager as parameter, and should return the dependency value, or a promise that resolves to it.
|
||||
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
|
||||
async function provider(manager: DependencyManager) {
|
||||
const value = await manager.resolve('dependencyIdentifier');
|
||||
function dependency(manager: DependencyManager) {
|
||||
const value = manager.resolve(otherDependency);
|
||||
return `The value is: ${valueA}`;
|
||||
}
|
||||
manager.register('other-identifier', provider);
|
||||
manager.register(dependency);
|
||||
manager.register(otherDependency);
|
||||
```
|
||||
|
||||
## Identifiers and typing
|
||||
## Typing
|
||||
|
||||
Any valid `Map` key can be used as identifier, but using a class allow the return value of the `resolve` method to be automatically typed:
|
||||
The reason we pass the provider to resolve a dependency is that it allow the `resolve` method to correctly type the returned value:
|
||||
|
||||
```typescript
|
||||
class MyDependency {}
|
||||
const A = () => 'foo';
|
||||
const B = () => 42;
|
||||
const C = () => ({});
|
||||
|
||||
const a = await manager.resolve(MyDependecy); //< `a` is of type `MyDependency`
|
||||
const b = await manager.resolve('dependency-identifier'); //< `b` is of type `unknown`
|
||||
const c = await manager.resolve<number>('dependency-identifier'); //< `c` is of type `number`
|
||||
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`
|
||||
```
|
||||
|
||||
Class with private constructor cannot be infered as class and thus need to be explicitly typed when resolved.
|
||||
## 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 name is already used.
|
||||
- the dependency is already registred.
|
||||
|
||||
The `resolve` method throw an error if:
|
||||
- the name doesn't exist (if no module has been registred with the given name).
|
||||
- the dependency is not registred.
|
||||
- a circular dependency is detected
|
||||
Reference in New Issue
Block a user