Skip to content

Commit

Permalink
Add more readme
Browse files Browse the repository at this point in the history
  • Loading branch information
drewjbartlett committed Nov 26, 2023
1 parent f668be2 commit 33476fa
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 14 deletions.
135 changes: 126 additions & 9 deletions README.md
Expand Up @@ -19,14 +19,131 @@ npm i @drewjbartlett/tiny-ioc --save

### Usage

Create a `container.ts` file that creates, registers, and then exports the container.

```ts
// container.ts
import { createContainer, Scope } from '@drewjbartlett/tiny-ioc';

const container = createContainer();

container.bind(MyClass, () => new MyClass(), Scope.Singleton);

container.registerFactory(DataSource, () => new DataSource(container.get(HttpClient)));
container.registerSingleton(HttpClient, () => new HttpClient());

export { container }
```

```ts
// some-other-file.ts

import { container } from 'path/to/container';
import { DataSource } from 'path/to/data-source';

export async function makeRequest() {
try {
const dataSource = container.get(DataSource);

return await dataSource.get('/foo/bar');
} catch (e) {
//
}
}
```

### API

- bind
- bindSingleton
- bindFactory
- bindOnce
- resetSingleton
- bound
- unbind
- swap
- get
- `bind` - Bind a dependency with a given scope.

```ts

```

- `bindSingleton` - Bind a dependency to the container as a singleton.

```ts

```

- `bindFactory` - Bind a dependency to the container as a factory. Each time the dependency is resolved the container will call the factory function.

```ts

```


- `bindOnce` - Only bind the given value if there is not already a binding.

```ts

```

- `get` - Attempt to resolve a given binding. Will throw if there is no binding found.

```ts

```

- `resetSingleton` - Reset a singleton value. If a value has been previously resolved and is registered as a singleton, this will keep the binding but reset the singleton value until the next resolve.

```ts

```

- `bound` - Determine if a binding exists or not.

```ts

```

- `unbind` - Remove the given binding from the container entirely.

```ts

```

- `swap` - Swap the old binding's value with the new value. This is useful when testing.

```ts

```

### Using in tests

```ts
// some-other-file.ts

import { container } from 'path/to/container';
import { DataSource } from 'path/to/data-source';

export async function makeRequest() {
try {
const dataSource = container.get(DataSource);

return await dataSource.get('/foo/bar');
} catch (e) {
//
}
}
```

```ts
// unit-test.test.ts

import { container } from 'path/to/container';
import { HttpClient } from 'path/to/http-client';
import { makeRequest } from 'path/top/make-request';

class DummyHttpClient {
get(url: string) {
return dummyData;
}
}

it('should make the request', () => {
container.swap(HttpClient, () => new DummyHttpClient());

await myRequest(); // this calls .get() on DummyHttpClient
})
```
12 changes: 7 additions & 5 deletions src/core/container.ts
Expand Up @@ -9,27 +9,29 @@ export function createContainer() {
const resolveBindings = new Map<Binding<any>, any>();

/**
* Bind a value with a given scope.
* Bind a dependency with a given scope.
*/
function bind<T>(binding: Binding<T>, value: FactoryFunction<T>, scope: Scope): void {
bindingConfigs.set(binding, { scope, value });
}

/**
* Create a singleton in the container. After the first resolve, this returns the same value each time.
* Bind a dependency to the container as a singleton.
*/
function bindSingleton<T>(binding: Binding<T>, factory: FactoryFunction<T>) {
bind(binding, factory, Scope.Singleton);
}

/**
* Bind a value to a factory. This will call the function every time and not store
* the value in memory as a singleton.
* Bind a dependency to the container as a factory. Each time the dependency is resolved the container will call the factory function.
*/
function bindFactory<T>(binding: Binding<T>, factory: FactoryFunction<T>) {
bind(binding, factory, Scope.Factory);
}

/**
* Only bind the given value if there is not already a binding.
*/
function bindOnce<T>(binding: Binding<T>, value: FactoryFunction<T>, scope: Scope): void {
if (bound(binding)) {
return;
Expand All @@ -50,7 +52,7 @@ export function createContainer() {
}

/**
* Determine if a function is bound or not.
* Determine if a binding exists or not.
*/
function bound<T>(binding: Binding<T>): boolean {
return bindingConfigs.has(binding);
Expand Down

0 comments on commit 33476fa

Please sign in to comment.