@drewjbartlett/tiny-ioc
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -8,3 +8,3 @@ { | ||
"type": "module", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"files": [ | ||
@@ -11,0 +11,0 @@ "dist" |
118
README.md
@@ -13,2 +13,7 @@ # Tiny IOC | ||
- ✅ lightweight - < 1kB | ||
- ✅ bind & unbind dependencies | ||
- ✅ bind singletons and reset if necessary | ||
- ✅ bind factories | ||
- ✅ support for swapping dependencies | ||
- ✅ makes testing a breeze | ||
@@ -23,3 +28,3 @@ ### Installation | ||
Create a `container.ts` file that creates, registers, and then exports the container. | ||
Create a `container.ts` file that creates, binds, and then exports the container. | ||
@@ -34,4 +39,4 @@ ```ts | ||
container.registerFactory(DataSource, () => new DataSource(container.get(HttpClient))); | ||
container.registerSingleton(HttpClient, () => new HttpClient()); | ||
container.bindFactory(DataSource, () => new DataSource(container.get(HttpClient))); | ||
container.bindSingleton(HttpClient, () => new HttpClient()); | ||
@@ -63,3 +68,9 @@ export { container } | ||
```ts | ||
import { createContainer, Scope } from '@drewjbartlett/tiny-ioc'; | ||
const container = createContainer(); | ||
container.bind(SomeClass, () => new SomeClass(container.get(AnotherClass)), Scope.Singleton); | ||
container.bind(AnotherClass, () => new AnotherClass(), Scope.Factory); | ||
``` | ||
@@ -70,3 +81,22 @@ | ||
```ts | ||
class Total { | ||
constructor(public readonly count: number) {} | ||
} | ||
let count = 0; | ||
container.bindFactory( | ||
Total, | ||
() => { | ||
count++; | ||
return new Total(count); | ||
}, | ||
); | ||
container.get(Total).count; // 1 | ||
container.get(Total).count; // 1 | ||
container.get(Total).count; // 1 | ||
container.get(Total).count; // 1 | ||
``` | ||
@@ -77,3 +107,21 @@ | ||
```ts | ||
class Total { | ||
constructor(public readonly count: number) {} | ||
} | ||
let count = 0; | ||
container.bindFactory( | ||
Total, | ||
() => { | ||
count++; | ||
return new Total(count); | ||
}, | ||
); | ||
container.get(Total).count; // 1 | ||
container.get(Total).count; // 2 | ||
container.get(Total).count; // 3 | ||
container.get(Total).count; // 4 | ||
``` | ||
@@ -85,3 +133,6 @@ | ||
```ts | ||
container.bindOnce(HttpClient, () => new HttpClient({ baseURL: 'baseURL 1' }), Scope.Singleton); | ||
container.bindOnce(HttpClient, () => new HttpClient({ baseURL: 'baseURL 2' }), Scope.Singleton); | ||
container.get(HttpClient).baseURL // 'baseURL 1' | ||
``` | ||
@@ -92,15 +143,38 @@ | ||
```ts | ||
container.get(SomeDependency); | ||
``` | ||
- `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. | ||
- `resetSingleton` - Reset a singleton value. | ||
If a value has been previously resolved and is bound as a singleton, this will keep the binding but reset the singleton value until the next resolve. Take the example below. Each time the singleton dependency is built the count will increase. Since it's a singleton `count` will always be 1. After resetting the singleton the new value is 2 since the factory function is called again. | ||
```ts | ||
let count = 0; | ||
container.bindSingleton( | ||
Total, | ||
() => { | ||
count++; | ||
return new Total(count); | ||
}, | ||
); | ||
container.get(Total).count // 1 | ||
container.get(Total).count // 1 | ||
container.resetSingleton(Total); | ||
container.get(Total).count // 2 | ||
``` | ||
- `bound` - Determine if a binding exists or not. | ||
- | ||
```ts | ||
container.bound(HttpClient); // false | ||
container.bindFactory(HttpClient, () => new HttpClient()); | ||
container.bound(HttpClient); // true | ||
``` | ||
@@ -111,3 +185,9 @@ | ||
```ts | ||
container.bindFactory(HttpClient, () => new HttpClient()); | ||
container.get(HttpClient); // HttpClient | ||
container.unbind(HttpClient); | ||
container.get(HttpClient); // throws NotBoundException | ||
``` | ||
@@ -117,4 +197,20 @@ | ||
There may be times where swapping a dependency is necessary. Especially when testing. `swap` allows for swapping out a dependency by a given class name. | ||
```ts | ||
class Tesla extends Car { | ||
} | ||
class Rivian extends Car { | ||
} | ||
container.bindFactory(Car, () => new Tesla()); | ||
container.get(Car); // Tesla | ||
container.swap(Car, () => new Rivian()); | ||
container.get(Car); // Rivian | ||
``` | ||
@@ -124,11 +220,13 @@ | ||
Unit testing is made very simple when using `tiny-ioc`. You can simply swap out the real dependency for any mock dependency and the tests will reference your mock instead of the real thing. | ||
```ts | ||
// some-other-file.ts | ||
// make-request.ts | ||
import { container } from 'path/to/container'; | ||
import { DataSource } from 'path/to/data-source'; | ||
import { HttpClient } from 'path/to/data-source'; | ||
export async function makeRequest() { | ||
try { | ||
const dataSource = container.get(DataSource); | ||
const dataSource = container.get(HttpClient); | ||
@@ -143,3 +241,3 @@ return await dataSource.get('/foo/bar'); | ||
```ts | ||
// unit-test.test.ts | ||
// make-request.test.ts | ||
@@ -159,4 +257,4 @@ import { container } from 'path/to/container'; | ||
await myRequest(); // this calls .get() on DummyHttpClient | ||
await myRequest(); // calls .get() on DummyHttpClient instead of HttpClient | ||
}) | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11181
247