import { DIKey } from '@/distage/model/DIKey'; import { BindingTags } from '@/distage/model/Activation'; import { Functoid } from '@/distage/core/Functoid'; /** * Base interface for all binding types */ export interface Binding { readonly key: DIKey; readonly tags: BindingTags; readonly kind: BindingKind; } /** * Types of bindings supported by distage */ export enum BindingKind { Instance = 'Instance', Class = 'Class', Factory = 'Factory', Alias = 'Alias', Set = 'Set', WeakSet = 'WeakSet', AssistedFactory = 'AssistedFactory', } /** * Binding that provides a pre-existing instance */ export interface InstanceBinding extends Binding { kind: BindingKind.Instance; instance: T; } /** * Binding that instantiates a class using its constructor */ export interface ClassBinding extends Binding { kind: BindingKind.Class; factory: Functoid; } /** * Binding that uses a factory function (Functoid) to create instances */ export interface FactoryBinding extends Binding { kind: BindingKind.Factory; factory: Functoid; } /** * Binding that creates an alias to another key */ export interface AliasBinding extends Binding { kind: BindingKind.Alias; target: DIKey; } /** * Binding that contributes an element to a set */ export interface SetBinding extends Binding> { kind: BindingKind.Set; elementKey: DIKey; element: ClassBinding | InstanceBinding | FactoryBinding; weak: boolean; } /** * Binding that contributes a weak element to a set. * Weak elements are only included if their dependencies are satisfied. */ export interface WeakSetBinding extends Binding> { kind: BindingKind.WeakSet; elementKey: DIKey; element: ClassBinding | InstanceBinding | FactoryBinding; } /** * Binding for assisted injection (factory bindings). * These allow creating multiple instances with runtime parameters * combined with DI-managed dependencies. */ export interface AssistedFactoryBinding extends Binding { kind: BindingKind.AssistedFactory; factory: Functoid; assistedParams: string[]; // Names of parameters to be provided at runtime } /** * Union type of all binding types */ export type AnyBinding = | InstanceBinding | ClassBinding | FactoryBinding | AliasBinding | SetBinding | WeakSetBinding | AssistedFactoryBinding; /** * Helper functions to create bindings */ export const Bindings = { instance(key: DIKey, instance: T, tags: BindingTags = BindingTags.empty()): InstanceBinding { return { key, tags, kind: BindingKind.Instance, instance, }; }, class( key: DIKey, implementation: new (...args: any[]) => T, tags: BindingTags = BindingTags.empty(), ): ClassBinding { return { key, tags, kind: BindingKind.Class, factory: Functoid.fromConstructor(implementation), }; }, factory( key: DIKey, factory: Functoid, tags: BindingTags = BindingTags.empty(), ): FactoryBinding { return { key, tags, kind: BindingKind.Factory, factory, }; }, alias( key: DIKey, target: DIKey, tags: BindingTags = BindingTags.empty(), ): AliasBinding { return { key, tags, kind: BindingKind.Alias, target, }; }, set( setKey: DIKey>, elementKey: DIKey, element: ClassBinding | InstanceBinding | FactoryBinding, weak: boolean = false, tags: BindingTags = BindingTags.empty(), ): SetBinding { return { key: setKey, tags, kind: BindingKind.Set, elementKey, element, weak, }; }, weakSet( setKey: DIKey>, elementKey: DIKey, element: ClassBinding | InstanceBinding | FactoryBinding, tags: BindingTags = BindingTags.empty(), ): WeakSetBinding { return { key: setKey, tags, kind: BindingKind.WeakSet, elementKey, element, }; }, assistedFactory( key: DIKey, factory: Functoid, assistedParams: string[] = [], tags: BindingTags = BindingTags.empty(), ): AssistedFactoryBinding { return { key, tags, kind: BindingKind.AssistedFactory, factory, assistedParams, }; }, };