Dependency injection (DI) is a design pattern that promotes loose coupling between components in a software system by allowing dependencies to be injected rather than hardcoded. In TypeScript, you can implement dependency injection using various approaches. Here's a simple example using classes and constructor injection:
Define the Dependency:
Create an interface or class that represents the dependency:
typescript// exampleService.ts
interface ExampleService {
doSomething(): void;
}
class ExampleServiceImpl implements ExampleService {
doSomething(): void {
console.log('Doing something...');
}
}
export { ExampleService, ExampleServiceImpl };
Create the Service that Needs the Dependency:
typescript// dependentService.ts
import { ExampleService } from './exampleService';
class DependentService {
private exampleService: ExampleService;
constructor(exampleService: ExampleService) {
this.exampleService = exampleService;
}
performAction(): void {
console.log('Performing action in dependent service');
this.exampleService.doSomething();
}
}
export { DependentService };
Configure the Dependency Injection Container:
Create a container to manage the dependencies. This could be a simple class or a framework like InversifyJS:
typescript// diContainer.ts
import { ExampleService, ExampleServiceImpl } from './exampleService';
import { DependentService } from './dependentService';
class DIContainer {
private exampleService: ExampleService;
private dependentService: DependentService;
constructor() {
this.exampleService = new ExampleServiceImpl(); // You can replace this with any other implementation
this.dependentService = new DependentService(this.exampleService);
}
getDependentService(): DependentService {
return this.dependentService;
}
}
export { DIContainer };
Usage:
typescript// main.ts
import { DIContainer } from './diContainer';
const container = new DIContainer();
const dependentService = container.getDependentService();
dependentService.performAction();
In this example, DependentService
relies on the ExampleService
interface, and the concrete implementation (ExampleServiceImpl
) is injected into DependentService
via its constructor. The DIContainer
is responsible for managing the dependencies and providing instances of the dependent services.
This is a simple example, and in a real-world application, you might want to use a more sophisticated dependency injection framework like InversifyJS or Tsyringe for more advanced features and better organization of your code.