Skip to content
IoC Arise Demo
npx @notjustcoders/ioc-arise
🔍 Scanning files... 📁 Found 12 classes, 8 interfaces
🔗 Analyzing dependencies... ✅ Graph validated
✨ container.gen.ts created!
✨ modules/todoModule.module.ts created!
// Type-safe resolution:
import { container } from './container.gen'
const service =
container.resolve(TodoService);
🚀 Ready to use!

IoC Arise

**Type-Safe Dependency Injection** for TypeScript Auto-generate container registration. Zero decorators. ~4KB runtime.
TypeScript 5+Zero Decorators~4KB RuntimeAST-Powered100% Type-Safe

Step 1: Write Your Code (Pure TypeScript, No Decorators!)

Section titled “Step 1: Write Your Code (Pure TypeScript, No Decorators!)”

Write your classes, interfaces, value objects, and factory functions in pure TypeScript:

💎 Value Objects

/**
* @value
*/
const config: IConfig = { apiUrl: 'https://api.example.com' };
/**
* @value
*/
const userService: IUserService = {
getUser: (id: string) => Promise.resolve({ id, name: 'User' })
};

🏭 Factory Functions (Separate Params)

/**
* @factory
*/
function createService(repo: IRepo1, config: IConfig) {
return (userId: string) => {
if (config.environment === 'prod') {
return new ProductionService(repo, userId);
}
return new DevelopmentService(repo, userId);
};
}

🏭 Factory Functions (Context Object)

/**
* @factory
*/
function createTodoUseCase(
context: { userRepo: IUserRepository, todoRepo: ITodoRepository }
) {
return (userId: string, title: string): void => {
const user = context.userRepo.getUser(userId);
console.log(`Creating todo for ${user}`);
context.todoRepo.saveTodo(title);
};
}

🏗️ Classes

interface IService1 {
getData(id: string): Promise<any>;
}
interface IRepo1 {
findById(id: string): Promise<any>;
}
class Repo1 implements IRepo1 {
async findById(id: string) { /* ... */ }
}
class Service1 implements IService1 {
constructor(private repo: IRepo1) {}
async getData(id: string) { /* ... */ }
}

📐 Abstract Classes

abstract class BaseRepo {
abstract findById(id: string): Promise<any>;
}
class Repo1 extends BaseRepo {
async findById(id: string) { /* ... */ }
}

🏗️ Modules

user/UserService.ts
export class UserService implements IUserService {
constructor(private userRepo: IUserRepository) {}
}
// todo/TodoService.ts
export class TodoService implements ITodoService {
constructor(
private todoRepo: ITodoRepository,
private userRepo: IUserRepository // Cross-module!
) {}
}

🔄 Lifecycle

// Singleton (default)
export class SingletonService {
constructor(private logger: ILogger) {}
}
// Transient
/**
* @scope transient
*/
export class TransientService {
constructor(private logger: ILogger) {}
}

Run the CLI command to auto-generate, or type the container registration code manually:

Terminal window
npx @notjustcoders/ioc-arise generate

If you used the CLI, it analyzes your code and generates two files. If you typed it manually, you’ll have the same structure:

container.gen.d.ts - Type-safe registry interface:

// container.gen.d.ts (auto-generated)
import type { IConfig } from './config';
import type { IUserService } from './userService';
import type { IService1 } from './services/IService1';
import type { IRepo1 } from './repositories/IRepo1';
import type { BaseRepo } from './repositories/BaseRepo';
export interface ContainerRegistry {
'IConfig': IConfig;
'IUserService': IUserService;
'IService1': IService1;
'IRepo1': IRepo1;
'BaseRepo': BaseRepo;
}

container.gen.ts - Container with all registrations:

// container.gen.ts (auto-generated)
import { Container, Lifecycle } from '@notjustcoders/di-container';
import type { ContainerRegistry } from './container.gen.d';
import { config } from './config';
import { userService } from './userService';
import { createService } from './createService';
import { Repo1, Service1 } from './classes';
export const container = new Container<ContainerRegistry>();
// All your value objects, factories, and classes are registered!
container.register('IConfig', { useValue: config });
container.register('IUserService', { useValue: userService });
container.register('IService1', {
useFactory: createService,
dependencies: ['IRepo1', 'IConfig']
});
container.register('IService1', {
useClass: Service1,
dependencies: ['IRepo1'],
lifecycle: Lifecycle.Singleton
});
// ... and more
import { container } from './container.gen';
const service = container.resolve('IService1');
// ^? IService1 - Full IntelliSense!
Terminal window
npm install @notjustcoders/di-container