Usage
This guide will show you how to use the @wroud/di
library in different setups: with decorators (stage 3), legacy decorators (stage 2), and plain JavaScript. Each section provides configuration tips and example code to help you get started quickly.
import { injectable, createService, ServiceContainerBuilder } from "@wroud/di";
interface ILoggerService {
log(message: string): void;
}
const ILoggerService = createService<ILoggerService>("ILoggerService");
@injectable()
class ConsoleLoggerService implements ILoggerService {
log(message: string) {
console.log(message);
}
}
@injectable(() => [ILoggerService])
class CounterService {
constructor(private logger: ILoggerService) {}
action() {
this.logger.log("Action executed");
}
}
const serviceProvider = new ServiceContainerBuilder()
.addSingleton(CounterService)
.addSingleton(ILoggerService, ConsoleLoggerService)
.build();
const counter = serviceProvider.getService(CounterService);
Decorators (stage 3)
To use the latest decorator features in @wroud/di
, you can utilize the stage 3 decorators. The @injectable
decorator allows you to specify class constructor dependencies so they can be automatically injected by the DI system.
Configuration
To use stage 3 decorators, ensure you have TypeScript version 5.0.0 or higher. Update your tsconfig.json
file as follows:
{
"compilerOptions": {
"target": "ESNext",
"lib": ["ESNext"], // or "Decorators"
"experimentalDecorators": false,
"emitDecoratorMetadata": false
}
}
Vite config
Browsers is not supporting decorators yet so you need to downgrade target to es2023 or lower to run it in dev.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
+ esbuild:{
+ target: "es2023"
+ },
plugins: [react()],
});
Migration from Legacy Decorators (stage 2)
If you are migrating from legacy decorators (stage 2), you need to update your tsconfig.json
:
{
"compilerOptions": {
- "experimentalDecorators": true,
- "emitDecoratorMetadata": true,
+ "lib": ["ESNext"], // or "Decorators"
}
}
You might need to install tslib
if your target environment does not support decorators.
npm install tslib
yarn add tslib
pnpm add tslib
bun add tslib
Legacy Decorators (stage 2)
If you prefer or need to use legacy decorators, you can still use @wroud/di
with them. The code structure remains the same.
Configuration
Enable legacy decorators in your tsconfig.json
:
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Plain JS
To use @wroud/di
without decorators, you can manually register class dependencies using ServiceRegistry
. This method is just as effective and allows you to manage dependencies without relying on decorators.
import {
createService,
ServiceContainerBuilder,
ServiceRegistry,
single,
} from "@wroud/di";
interface ILoggerService {
log(message: string): void;
}
const ILoggerService = createService<ILoggerService>("ILoggerService");
class ConsoleLoggerService implements ILoggerService {
log(message: string) {
console.log(message);
}
}
class CounterService {
constructor(private logger: ILoggerService) {}
action() {
this.logger.log("Action executed");
}
}
function configure() {
ServiceRegistry.register(CounterService, {
name: "CounterService",
dependencies: [single(ILoggerService)],
});
ServiceRegistry.register(ConsoleLoggerService, {
name: "ConsoleLoggerService",
dependencies: [],
});
const serviceProvider = new ServiceContainerBuilder()
.addSingleton(CounterService)
.addSingleton(ILoggerService, ConsoleLoggerService)
.build();
const counter = serviceProvider.getService(CounterService);
}