KOIN - Kotlin simple Dependency Injection Framework for JavaScript/Browser platform
—
Module definition DSL for organizing and declaring dependencies with singletons, factories, scoped instances, and constructor-based definitions.
Define modules with dependency definitions using the fluent DSL.
/**
* Define a module with dependency definitions
* @param createdAtStart - Whether to create instances immediately on startup (default: false)
* @param moduleDeclaration - Module configuration function
* @returns Module instance
*/
function module(
createdAtStart?: boolean,
moduleDeclaration: ModuleDeclaration
): Module;
/**
* Define a module with only the declaration function
* @param moduleDeclaration - Module configuration function
* @returns Module instance
*/
function module(moduleDeclaration: ModuleDeclaration): Module;
/**
* Create a Koin configuration
* @param declaration - Application configuration function
* @returns KoinConfiguration instance
*/
function koinConfiguration(declaration: KoinAppDeclaration): KoinConfiguration;Usage Examples:
import { module } from "koin-core";
// Basic module definition
const appModule = module((module) => {
module.single(null, false, () => new DatabaseService());
module.factory(null, () => new ApiClient());
});
// Module with eager creation
const eagerModule = module(true, (module) => {
module.single(null, true, () => new ConfigurationService());
});Define different types of dependencies within modules.
class Module {
/** Module unique identifier */
readonly id: string;
/** Whether module is loaded */
readonly isLoaded: boolean;
/**
* Define singleton instance - created once and reused
* @param qualifier - Optional qualifier for instance identification
* @param createdAtStart - Whether to create immediately (default: false)
* @param definition - Function that creates the instance
* @returns KoinDefinition for additional configuration
*/
single<T>(
qualifier?: Qualifier,
createdAtStart?: boolean,
definition: Definition<T>
): KoinDefinition<T>;
/**
* Define factory instance - new instance every request
* @param qualifier - Optional qualifier for instance identification
* @param definition - Function that creates the instance
* @returns KoinDefinition for additional configuration
*/
factory<T>(qualifier?: Qualifier, definition: Definition<T>): KoinDefinition<T>;
/**
* Define scoped instances within named scope
* @param qualifier - Scope qualifier
* @param scopeSet - Scope configuration function
*/
scope(qualifier: Qualifier, scopeSet: (scopeDSL: ScopeDSL) => void): void;
scope<T>(scopeSet: (scopeDSL: ScopeDSL) => void): void;
/**
* Include other modules
* @param modules - Modules to include
*/
includes(...modules: Module[]): void;
includes(modules: Module[]): void;
/**
* Module composition operators
*/
plus(module: Module): Module[];
plus(modules: Module[]): Module[];
}Usage Examples:
import { module, named } from "koin-core";
const appModule = module((module) => {
// Singleton - created once, reused
module.single(null, false, () => new DatabaseConnection("localhost:5432"));
// Qualified singleton
module.single(named("primary"), false, () => new DatabaseConnection("primary-db:5432"));
// Factory - new instance each time
module.factory(null, () => new HttpRequest());
// Qualified factory
module.factory(named("api"), () => new ApiClient("https://api.example.com"));
// Eager singleton - created at startup
module.single(null, true, () => new ConfigurationLoader());
});Enhanced DSL functions for constructor-based dependency definitions with automatic parameter resolution.
/**
* Constructor-based singleton definition with 0 parameters
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function singleOf<T>(constructor: () => T): BeanDefinition<T>;
/**
* Constructor-based singleton definition with 1 parameter
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function singleOf<T, P1>(constructor: (p1: P1) => T): BeanDefinition<T>;
/**
* Constructor-based singleton definition with 2 parameters
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function singleOf<T, P1, P2>(constructor: (p1: P1, p2: P2) => T): BeanDefinition<T>;
// Additional variants for up to 22 parameters...
/**
* Constructor-based factory definition with 0 parameters
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function factoryOf<T>(constructor: () => T): BeanDefinition<T>;
/**
* Constructor-based factory definition with 1 parameter
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function factoryOf<T, P1>(constructor: (p1: P1) => T): BeanDefinition<T>;
// Additional factoryOf variants for up to 22 parameters...
/**
* Constructor-based scoped definition with 0 parameters
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function scopedOf<T>(constructor: () => T): BeanDefinition<T>;
/**
* Constructor-based scoped definition with 1 parameter
* @param constructor - Constructor function
* @returns BeanDefinition for additional configuration
*/
function scopedOf<T, P1>(constructor: (p1: P1) => T): BeanDefinition<T>;
// Additional scopedOf variants for up to 22 parameters...Usage Examples:
import { module, singleOf, factoryOf } from "koin-core";
class DatabaseService {
constructor(connectionString) {
this.connectionString = connectionString;
}
}
class ApiClient {
constructor(baseUrl, timeout) {
this.baseUrl = baseUrl;
this.timeout = timeout;
}
}
const appModule = module((builder) => {
// Constructor-based definitions automatically resolve parameters
builder.singleOf(DatabaseService); // Auto-resolves constructor parameters
builder.factoryOf(ApiClient); // Auto-resolves constructor parameters
// Dependencies for constructors
builder.single(() => "mongodb://localhost:27017"); // For DatabaseService
builder.single(() => "https://api.example.com"); // For ApiClient baseUrl
builder.single(() => 5000); // For ApiClient timeout
});Define scoped dependencies that live within specific lifecycle boundaries.
class Module {
/**
* Define scoped instances within named scope
* @param qualifier - Scope identifier
* @param scopeSet - Scope configuration function
* @returns Module for chaining
*/
scope(qualifier: Qualifier, scopeSet: (builder: ScopeBuilder) => void): Module;
}
class ScopeBuilder {
/**
* Define scoped instance within scope
* @param definition - Function that creates the instance
* @returns BeanDefinition for additional configuration
*/
scoped<T>(definition: (scope: Scope, parameters: ParametersHolder) => T): BeanDefinition<T>;
/**
* Define qualified scoped instance
* @param qualifier - Qualifier for instance identification
* @param definition - Function that creates the instance
* @returns BeanDefinition for additional configuration
*/
scoped<T>(
qualifier: Qualifier,
definition: (scope: Scope, parameters: ParametersHolder) => T
): BeanDefinition<T>;
/**
* Define factory instance within scope
* @param definition - Function that creates the instance
* @returns BeanDefinition for additional configuration
*/
factory<T>(definition: (scope: Scope, parameters: ParametersHolder) => T): BeanDefinition<T>;
/**
* Define qualified factory instance within scope
* @param qualifier - Qualifier for instance identification
* @param definition - Function that creates the instance
* @returns BeanDefinition for additional configuration
*/
factory<T>(
qualifier: Qualifier,
definition: (scope: Scope, parameters: ParametersHolder) => T
): BeanDefinition<T>;
}Usage Examples:
import { module, named } from "koin-core";
const webModule = module((builder) => {
// Define a session scope
builder.scope(named("session"), (scopeBuilder) => {
// User session - lives for duration of session scope
scopeBuilder.scoped(() => new UserSession());
// Shopping cart - lives for duration of session scope
scopeBuilder.scoped(() => new ShoppingCart());
// HTTP request factory - new instance per request within session
scopeBuilder.factory(() => new HttpRequest());
});
// Define a request scope
builder.scope(named("request"), (scopeBuilder) => {
scopeBuilder.scoped(() => new RequestContext());
scopeBuilder.scoped(named("api"), () => new ApiRequestHandler());
});
});Combine and organize modules for complex applications.
class Module {
/**
* Include other modules in this module
* @param modules - Modules to include
* @returns Module for chaining
*/
includes(...modules: Module[]): Module;
/**
* Combine modules using plus operator
* @param module - Module to combine
* @returns New combined module
*/
plus(module: Module): Module;
/**
* Combine with multiple modules
* @param modules - Modules to combine
* @returns New combined module
*/
plus(modules: Module[]): Module;
}Usage Examples:
import { module } from "koin-core";
const coreModule = module((builder) => {
builder.single(() => new Logger());
builder.single(() => new ConfigService());
});
const databaseModule = module((builder) => {
builder.single(() => new DatabaseConnection());
builder.factory(() => new Repository());
});
const apiModule = module((builder) => {
builder.factory(() => new ApiClient());
builder.single(() => new AuthService());
});
// Combine modules using includes
const appModule = module((builder) => {
builder.includes(coreModule, databaseModule, apiModule);
builder.single(() => new AppService());
});
// Combine modules using plus operator
const combinedModule = coreModule.plus(databaseModule).plus(apiModule);
// Alternative combination syntax
const allModules = coreModule.plus([databaseModule, apiModule]);Configure bean definitions with type binding and lifecycle callbacks.
interface BeanDefinition<T> {
/**
* Bind additional compatible types for injection
* @param clazz - Class or interface to bind
* @returns BeanDefinition for chaining
*/
bind<S>(clazz: new (...args: any[]) => S): BeanDefinition<T>;
/**
* Bind additional compatible type using generics
* @returns BeanDefinition for chaining
*/
bind<S>(): BeanDefinition<T>;
/**
* Bind multiple compatible types
* @param classes - Array of classes to bind
* @returns BeanDefinition for chaining
*/
binds(classes: (new (...args: any[]) => any)[]): BeanDefinition<T>;
/**
* Add cleanup callback when instance is closed
* @param callback - Cleanup function
* @returns BeanDefinition for chaining
*/
onClose(callback: (instance: T) => void): BeanDefinition<T>;
}Usage Examples:
import { module } from "koin-core";
// Interfaces for binding
class DatabaseService {}
class IDataService {}
class ILoggable {}
const appModule = module((builder) => {
// Bind additional types for polymorphic injection
builder
.single(() => new DatabaseService())
.bind(IDataService)
.bind(ILoggable)
.onClose((instance) => {
console.log("Closing database service");
instance.close();
});
// Bind multiple types at once
builder
.factory(() => new HttpClient())
.binds([IHttpClient, IRequestHandler])
.onClose((instance) => instance.cleanup());
});/** Function type for module declarations */
type ModuleDeclaration = (builder: ModuleBuilder) => void;
/** Function type for dependency definitions */
type Definition<T> = (scope: Scope, parameters: ParametersHolder) => T;
/** Function type for cleanup callbacks */
type OnCloseCallback<T> = (instance: T) => void;
/** Module builder interface for DSL */
interface ModuleBuilder {
single<T>(definition: Definition<T>): BeanDefinition<T>;
single<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;
factory<T>(definition: Definition<T>): BeanDefinition<T>;
factory<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;
scope(qualifier: Qualifier, scopeSet: (builder: ScopeBuilder) => void): Module;
}
/** Scope builder interface for scoped definitions */
interface ScopeBuilder {
scoped<T>(definition: Definition<T>): BeanDefinition<T>;
scoped<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;
factory<T>(definition: Definition<T>): BeanDefinition<T>;
factory<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;
}
/** Bean definition kinds */
enum BeanDefinitionKind {
Singleton = "Singleton",
Factory = "Factory",
Scoped = "Scoped"
}
/** Core bean definition class */
class BeanDefinition<T> {
scopeQualifier: Qualifier;
primaryType: any;
qualifier: Qualifier;
definition: Definition<T>;
kind: BeanDefinitionKind;
secondaryTypes: any[];
}Install with Tessl CLI
npx tessl i tessl/maven-io-insert-koin--koin-core-js