or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bindings.mdcontainer.mddependency-injection.mdindex.mdmodules.mdparsing-utilities.mdresolver.mdtesting.md
tile.json

tessl/npm-adonisjs--fold

Simplest and straightforward implementation of IoC container in JavaScript

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@adonisjs/fold@10.2.x

To install, run

npx @tessl/cli install tessl/npm-adonisjs--fold@10.2.0

index.mddocs/

AdonisJS Fold

AdonisJS Fold is a lightweight and straightforward implementation of an Inversion of Control (IoC) container specifically designed for JavaScript and TypeScript applications. It focuses on simplicity and readability while enabling dependency injection patterns that help create loosely coupled systems.

Package Information

  • Package Name: @adonisjs/fold
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @adonisjs/fold

Core Imports

import { 
  Container, 
  inject, 
  ContainerResolver,
  moduleCaller,
  moduleImporter,
  moduleExpression,
  parseBindingReference
} from "@adonisjs/fold";

For CommonJS:

const { 
  Container, 
  inject, 
  ContainerResolver,
  moduleCaller,
  moduleImporter,
  moduleExpression,
  parseBindingReference
} = require("@adonisjs/fold");

Basic Usage

import { Container, inject } from "@adonisjs/fold";

// Create a container
const container = new Container();

// Register bindings
container.bindValue("database_url", "postgresql://localhost:5432/mydb");
container.singleton("logger", () => new Logger());

// Use dependency injection with decorators
@inject()
class UserService {
  constructor(
    private logger: Logger,
    private databaseUrl: string
  ) {}
  
  async getUsers() {
    this.logger.info("Fetching users from", this.databaseUrl);
    // Implementation
  }
}

// Resolve dependencies
const userService = await container.make(UserService);

Architecture

AdonisJS Fold is built around several key components:

  • Container: Main IoC container for registering and resolving dependencies
  • ContainerResolver: Isolated resolver instance for scoped dependency resolution
  • Dependency Injection: Decorator-based automatic dependency resolution using TypeScript reflection
  • Binding System: Multiple binding types including values, factories, singletons, and contextual bindings
  • Module Utilities: Helper functions for working with dynamic imports and string-based module references
  • Testing Support: Swap/mock system for replacing dependencies during testing

Capabilities

Container Management

Core IoC container functionality for registering dependencies, creating instances, and managing the dependency lifecycle.

class Container<KnownBindings extends Record<any, any>> {
  constructor(options?: ContainerOptions);
  make<Binding>(binding: Binding, runtimeValues?: any[], createError?: ErrorCreator): Promise<Make<Binding>>;
  createResolver(): ContainerResolver<KnownBindings>;
}

Container Management

Dependency Injection

Automatic dependency injection using TypeScript decorators and reflection metadata for seamless constructor and method parameter resolution.

function inject(): <C extends Function>(target: C) => void;
function inject(): (target: any, propertyKey: string | symbol) => void;

Dependency Injection

Binding Registration

Multiple binding types for registering dependencies including direct values, factory functions, singletons, and contextual bindings.

class Container<KnownBindings extends Record<any, any>> {
  bind<Binding>(binding: Binding, resolver: BindingResolver<KnownBindings, any>): void;
  bindValue<Binding>(binding: Binding, value: any): void;
  singleton<Binding>(binding: Binding, resolver: BindingResolver<KnownBindings, any>): void;
}

Binding Registration

Container Resolver

Isolated resolver instances that can resolve dependencies and create class instances without modifying the parent container.

class ContainerResolver<KnownBindings extends Record<any, any>> {
  make<Binding>(binding: Binding, runtimeValues?: any[], createError?: ErrorCreator): Promise<Make<Binding>>;
  call<Value, Method>(value: Value, method: Method, runtimeValues?: any[], createError?: ErrorCreator): Promise<ReturnType<Value[Method]>>;
  bindValue<Binding>(binding: Binding, value: any): void;
}

Container Resolver

Module Utilities

Helper functions for working with dynamic imports, string-based module references, and creating callable functions from class constructors.

function moduleCaller(target: Constructor<any>, method: string): {
  toCallable<T>(containerOrResolver: Container<any> | ContainerResolver<any>): ModuleCallable<T, any[]>;
  toHandleMethod<T>(containerOrResolver: Container<any> | ContainerResolver<any>): ModuleHandler<T, any[]>;
};

function moduleImporter(importFn: () => Promise<{ default: Constructor<any> }>, method: string): {
  toCallable<T>(containerOrResolver: Container<any> | ContainerResolver<any>): ModuleCallable<T, any[]>;
  toHandleMethod<T>(containerOrResolver: Container<any> | ContainerResolver<any>): ModuleHandler<T, any[]>;
};

Module Utilities

Testing Support

Swap and mock functionality for replacing dependencies during testing, with easy restoration capabilities.

class Container<KnownBindings extends Record<any, any>> {
  swap<Binding>(binding: AbstractConstructor<any>, resolver: BindingResolver<KnownBindings, any>): void;
  restore(binding: AbstractConstructor<any>): void;
  restoreAll(bindings?: AbstractConstructor<any>[]): void;
}

Testing Support

String Parsing Utilities

Utility functions for parsing binding references from magic strings, class references, and lazy import references.

function parseBindingReference(
  binding: string | [LazyImport<Constructor<any>> | Constructor<any>, any?]
): Promise<{ moduleNameOrPath: string; method: string }>;

String Parsing Utilities

Core Types

type BindingKey = string | symbol | AbstractConstructor<any>;

type BindingResolver<KnownBindings extends Record<any, any>, Value> = (
  resolver: ContainerResolver<KnownBindings>,
  runtimeValues?: any[]
) => Value | Promise<Value>;

type Make<T> = T extends AbstractConstructor<infer A> ? A : never;

type ErrorCreator = (message: string) => Exception;

type HookCallback<KnownBindings extends Record<any, any>, Value> = (
  value: Value,
  resolver: ContainerResolver<KnownBindings>
) => void | Promise<void>;

interface ContainerOptions {
  emitter?: {
    emit(event: string | symbol, ...values: any[]): any;
  };
}

type ModuleCallable<T, Args extends any[]> = T extends undefined
  ? (resolver: ContainerResolver<any> | Container<any>, ...args: Args) => Promise<any>
  : (...args: Args) => Promise<any>;

type ModuleHandler<T, Args extends any[]> = T extends undefined
  ? {
      name?: string;
      handle(resolver: ContainerResolver<any> | Container<any>, ...args: Args): Promise<any>;
    }
  : {
      name?: string;
      handle(...args: Args): Promise<any>;
    };