Security News
Opengrep Emerges as Open Source Alternative Amid Semgrep Licensing Controversy
Opengrep forks Semgrep to preserve open source SAST in response to controversial licensing changes.
@drewjbartlett/tiny-ioc
Advanced tools
`tiny-ioc` is a lightweight (less than 1kB) dependency injection / IOC container for TypeScript.
tiny-ioc
is a lightweight (less than 1kB) dependency injection / IOC container for TypeScript.
npm i @drewjbartlett/tiny-ioc --save
Create a container.ts
file that creates, binds, and then exports the container.
// container.ts
import { createContainer, Scope } from '@drewjbartlett/tiny-ioc';
const container = createContainer();
container.bind(MyClass, () => new MyClass(), Scope.Singleton);
container.bindFactory(DataSource, () => new DataSource(container.get(HttpClient)));
container.bindSingleton(HttpClient, () => new HttpClient());
export { container }
// 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) {
//
}
}
bind<T>(binding: Binding<T>, value: FactoryFunction<T>, scope: Scope): void
Bind a dependency with a given scope.
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);
bindSingleton<T>(binding: Binding<T>, factory: FactoryFunction<T>): void
Bind a dependency to the container as a singleton.
class Total {
constructor(public readonly count: number) {}
}
let count = 0;
container.bindSingleton(
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
bindFactory<T>(binding: Binding<T>, factory: FactoryFunction<T>): void
Bind a dependency to the container as a factory. Each time the dependency is resolved the container will call the factory function.
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
bindOnce<T>(binding: Binding<T>, value: FactoryFunction<T>, scope: Scope): void
Only bind the given value if there is not already a binding.
container.bindFactory(HttpClient, () => new HttpClient({ baseURL: 'baseURL 1' }));
container.bindOnce(HttpClient, () => new HttpClient({ baseURL: 'baseURL 2' }), Scope.Singleton);
container.get(HttpClient).baseURL // 'baseURL 1'
get<T>(binding: Binding<T>): T
Attempt to resolve a given binding. Will throw a NotBoundException
if there is no binding found.
container.get(SomeDependency);
resetSingleton<T>(binding: Binding<T>): void
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.
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<T>(binding: Binding<T>): boolean
Determine if a binding exists or not.
container.bound(HttpClient); // false
container.bindFactory(HttpClient, () => new HttpClient());
container.bound(HttpClient); // true
unbind<T>(binding: Binding<T>): void
Remove the given binding from the container entirely.
container.bindFactory(HttpClient, () => new HttpClient());
container.get(HttpClient); // HttpClient
container.unbind(HttpClient);
container.get(HttpClient); // throws NotBoundException
swap<T>(oldBinding: Binding<T>, newBinding: FactoryFunction<T>): void
Swap the old binding's value with the new value. This is useful when testing.
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.
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
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.
// make-request.ts
import { container } from 'path/to/container';
import { HttpClient } from 'path/to/http-client';
export async function makeRequest() {
try {
const dataSource = container.get(HttpClient);
return await dataSource.get('/foo/bar');
} catch (e) {
//
}
}
// make-request.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(); // calls .get() on DummyHttpClient instead of HttpClient
})
FAQs
`tiny-ioc` is a lightweight (less than 1kB) dependency injection / IOC container for TypeScript.
We found that @drewjbartlett/tiny-ioc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Opengrep forks Semgrep to preserve open source SAST in response to controversial licensing changes.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.