Skip to content

StatelessStudio/hidi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

35 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

hidi - Hierarchical Dependency Injection for TypeScript

A lightweight, type-safe dependency injection container for TypeScript applications. Simplify dependency management with support for hierarchical containers, explicit key registration, and a minimal API.

Software Development by Stateless Studio

Features

  • 🎯 Type-Safe - Full TypeScript support with generic types for type-safe dependency retrieval
  • πŸ”‘ Flexible Key Registration - Register dependencies using string keys or class constructors
  • 🌳 Hierarchical Containers - Support for parent-child container relationships with automatic fallback
  • ⚑ Lightweight - Minimal API surface with zero external dependencies
  • πŸ§ͺ Well-Tested - 100% code coverage with comprehensive test suite
  • πŸ“¦ Production-Ready - Simple, predictable behavior for reliable dependency management

Installation

npm install hidi

Quick Start

Basic Registration and Retrieval

Register dependencies using string keys:

import { DependencyContainer } from 'hidi';

const container = new DependencyContainer();

// Register a dependency with a string key
container.register('logger', console.log);

// Retrieve the dependency
const logger = container.get('logger');

Using Class Constructors as Keys

Register and retrieve using class constructors:

class DatabaseService {
  connect() {
    console.log('Connected to database');
  }
}

const dbService = new DatabaseService();
container.register(DatabaseService, dbService);

// Retrieve by class constructor
const db = container.get(DatabaseService);
db?.connect(); // "Connected to database"

API Reference

register(key, injectable)

Register a dependency in the container.

// Using a string key
container.register('apiUrl', 'https://api.example.com');

// Using a class constructor
class UserService {}
container.register(UserService, new UserService());

get(key)

Retrieve a dependency from the container. Searches parent containers if not found locally. Returns undefined if not found.

const value = container.get('apiUrl');
const userService = container.get(UserService);

require(key)

Retrieve a dependency, or throw an error if the dependency is not found in the container hierarchy.

try {
  const config = container.require('appConfig');
}
catch (error) {
  console.error('Required dependency not found:', error.message);
}

has(key)

Check if a dependency exists in the container or any parent container.

if (container.has('logger')) {
  const logger = container.get('logger');
}

extend()

Create a child container that inherits from the current container. Child containers can override parent dependencies.

const parentContainer = new DependencyContainer();
parentContainer.register('dbUrl', 'postgres://prod');

const childContainer = parentContainer.extend();
console.log(childContainer.get('dbUrl')); // "postgres://prod"

// Override in child
childContainer.register('dbUrl', 'postgres://dev');
console.log(childContainer.get('dbUrl')); // "postgres://dev"

setParent(parent)

Manually set the parent container for a dependency container.

const child = new DependencyContainer();
const parent = new DependencyContainer();
child.setParent(parent);

Usage Examples

Application Configuration

interface Config {
  apiUrl: string;
  timeout: number;
}

const container = new DependencyContainer();

container.register('config', {
  apiUrl: 'https://api.example.com',
  timeout: 5000
} as Config);

const config = container.get<Config>('config');

Service Dependencies

class Logger {
  log(message: string) {
    console.log(`[LOG] ${message}`);
  }
}

class UserRepository {
  constructor(private logger: Logger) {}
  
  findUser(id: number) {
    this.logger.log(`Finding user ${id}`);
    // ... database query
  }
}

const logger = new Logger();
const userRepo = new UserRepository(logger);

container.register(Logger, logger);
container.register(UserRepository, userRepo);

// Later...
const repo = container.require(UserRepository);

Contributing & Development

See contributing.md for information on how to develop or contribute to this project!

License

See LICENSE.md

About

Hierarchical Dependency Injection for TypeScript

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •