resolvd
TypeScript icon, indicating that this package has built-in type declarations

2.0.1 • Public • Published

resolvd

Simple, small, and type-safe inversion of control/dependency injection for JavaScript & TypeScript with zero dependencies

Upgrading from 1.x -> 2.x

Version 2 is fully promise based, but the only change that's necessary is awaiting the result of ioc().resolve:

import { ioc } from 'resolvd';
 
const container = ioc();
 
// throws:
// There are circular dependencies in your service definitions:
// * b -> a -> c -> b
await container.resolve({ /** ...service definitions */ });

Circular dependencies

resolvd will identify circular dependencies and throw an error message containing the offending services:

import { ioc } from 'resolvd';
 
// A requires B, which requires C, which requires A, which requires B, etc.
const serviceA = (_: { serviceB: unknown }) => {};
const serviceB = (_: { serviceC: unknown }) => {};
const serviceC = (_: { serviceA: unknown }) => {};
 
interface Services {
  a: ReturnType<typeof serviceA>,
  b: ReturnType<typeof serviceB>,
  c: ReturnType<typeof serviceC>,
}
 
const container = ioc<Services>();
 
// throws:
// There are circular dependencies in your service definitions:
// * b -> a -> c -> b
container.resolve({
  a: container.define(serviceA, { serviceB: 'b' }),
  b: container.define(serviceB, { serviceC: 'c' }),
  c: container.define(serviceC, { serviceA: 'a' }),
});

Type-safe

Trying to define a dependency of the wrong type will cause an TypeScript error - stopping the issue at compile time

Usage

import { ioc } from 'resolvd';
 
interface ILogger {
  log(msg: string): void;
}
 
interface IClock {
  now(): Date;
}
 
interface PublicServices {
  logger: ILogger;
  someObject: object;
}
 
interface PrivateServices {
  clock: IClock;
}
 
const somePreConstructedObject = {
  foo: 'bar',
};
 
const consoleLogger = async (deps: { someParamName: IClock }): Promise<ILogger> => ({
  log(msg) {
    console.log(`[${deps.someParamName.now().toISOString()}${msg}`);
  },
});
 
const clock = (): IClock => ({
  now: () => new Date,
});
 
// create a new container with the specified services available
const container = ioc<PublicServices, PrivateServices>();
// resolve the service definitions into an object of type `PublicServices`
const services = await container.resolve({
  // use `container.define` to define each service definition
  logger: container.define(consoleLogger, { someParamName: 'clock' }),
  clock: container.define(clock, {}),
  // always provide a new instance of this service to whatever is requesting it
  someObject: container.define(_ => somePreConstructedObject, { alwaysNewInstance: true }),
});
 
// the PublicServices are now available!
services.logger.log('hello, world!'); // [2020-06-10T19:26:34.000Z] hello, world!

Services should only be registered using ioc().define(...)!

Dependents (0)

Package Sidebar

Install

npm i resolvd

Weekly Downloads

0

Version

2.0.1

License

MIT

Unpacked Size

48.2 kB

Total Files

22

Last publish

Collaborators

  • leightonrthomas