Lab 08: Dependency Injection

Time: 40 minutes | Level: Advanced | Docker: docker run -it --rm node:20-alpine sh

Build a type-safe dependency injection system using tsyringe: decorators, interface tokens, constructor/property injection, singletons, and testing with mock containers.


Step 1: Environment Setup

docker run -it --rm node:20-alpine sh
npm install -g typescript ts-node
mkdir lab08 && cd lab08
npm init -y
npm install tsyringe reflect-metadata
echo '{
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES2020",
    "strict": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true
  }
}' > tsconfig.json

💡 experimentalDecorators and emitDecoratorMetadata are required for tsyringe. These enable TypeScript to emit type metadata at runtime for reflection-based injection.


Step 2: Basic @injectable and Container

The foundation — registering and resolving services:


Step 3: Interface Tokens for Abstraction

Use injection tokens to depend on interfaces, not implementations:


Step 4: @singleton Decorator

Ensure a single instance is shared:

💡 Without @singleton(), each resolve() creates a new instance. With it, the container caches the first instance.


Step 5: Value and Factory Registration

Register instances, values, and factory functions:


Step 6: Child Containers and Scoped Injection

Scope dependencies per request:


Step 7: Testing with Mock Container

Swap implementations for testing:


Step 8: Capstone — Full DI Application

Run:

📸 Verified Output:


Summary

Concept
Decorator/API
Use Case

Mark injectable

@injectable()

Enable DI for a class

Singleton scope

@singleton()

Share one instance

Inject by token

@inject(TOKEN)

Interface-based injection

Register class

container.register(T, {useClass: C})

Bind interface to impl

Register value

container.register(T, {useValue: v})

Inject config/constants

Register factory

container.register(T, {useFactory: f})

Dynamic construction

Resolve

container.resolve(Class)

Get instance with deps

Child container

container.createChildContainer()

Scoped/test injection

Last updated