### Installing TypeDI and Dependencies - Bash Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/01-getting-started.md This command installs the core TypeDI library and the `reflect-metadata` package, which is essential for enabling decorator metadata emission in TypeScript applications. ```bash npm install typedi reflect-metadata ``` -------------------------------- ### Installing TypeDI and Reflect-metadata (Bash) Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/01-getting-started.md This command installs the necessary TypeDI and reflect-metadata packages using npm, which are prerequisites for enabling dependency injection functionality in JavaScript environments. ```bash npm install typedi reflect-metadata ``` -------------------------------- ### Basic TypeDI Container Usage (JavaScript) Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/01-getting-started.md This JavaScript example demonstrates the fundamental process of registering a class with the TypeDI container and subsequently retrieving an instance. It illustrates how TypeDI manages class instantiation and provides a cached version if available, ensuring efficient dependency resolution. ```javascript import 'reflect-metadata'; import { Container } from 'typedi'; class ExampleClass { print() { console.log('I am alive!'); } } /** Register this class to the TypeDI container */ Container.set({ id: ExampleClass, type: ExampleClass }); /** Request an instance of ExampleClass from TypeDI. */ const classInstance = Container.get(ExampleClass); /** We received an instance of ExampleClass and ready to work with it. */ classInstance.print(); ``` -------------------------------- ### Demonstrating Basic Dependency Injection - TypeScript Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/01-getting-started.md This example illustrates how to use TypeDI's `@Service()` decorator to mark classes for dependency injection and how to retrieve instances using `Container.get()`. It shows automatic injection of `ExampleInjectedService` into `ExampleService`'s constructor. ```ts import { Container, Service } from 'typedi'; @Service() class ExampleInjectedService { printMessage() { console.log('I am alive!'); } } @Service() class ExampleService { constructor( // because we annotated ExampleInjectedService with the @Service() // decorator TypeDI will automatically inject an instance of // ExampleInjectedService here when the ExampleService class is requested // from TypeDI. public injectedService: ExampleInjectedService ) {} } const serviceInstance = Container.get(ExampleService); // we request an instance of ExampleService from TypeDI serviceInstance.injectedService.printMessage(); // logs "I am alive!" to the console ``` -------------------------------- ### Importing Reflect-Metadata - TypeScript Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/01-getting-started.md This line imports the `reflect-metadata` polyfill, which must be the very first import in your application's entry file to enable decorator metadata reflection, a prerequisite for TypeDI's functionality. ```ts import 'reflect-metadata'; // Your other imports and initialization code // comes here after you imported the reflect-metadata package! ``` -------------------------------- ### Configuring TypeScript for Decorators - JSON Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/01-getting-started.md These two lines in `tsconfig.json`'s `compilerOptions` enable the emission of design-time type metadata for decorators (`emitDecoratorMetadata`) and support for experimental decorator syntax (`experimentalDecorators`), both crucial for TypeDI to function correctly. ```json "emitDecoratorMetadata": true, "experimentalDecorators": true, ``` -------------------------------- ### Installing TypeDI and Reflect-Metadata via NPM Source: https://github.com/typestack/typedi/blob/develop/README.md This command installs the `typedi` library and its required peer dependency, `reflect-metadata`, using npm. `reflect-metadata` is crucial for enabling decorator-based dependency injection in TypeScript by providing design-time type metadata. ```bash npm install typedi reflect-metadata ``` -------------------------------- ### Directly Resolving Dependencies with TypeDI Container.get() Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/02-basic-usage-guide.md This example showcases the direct use of `Container.get()` to resolve various types of dependencies. It demonstrates retrieving instances of `@Service()` annotated classes, values registered with `Token`s, and values registered with string identifiers, highlighting the flexibility of TypeDI's container. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service, Token } from 'typedi'; const myToken = new Token('SECRET_VALUE_KEY'); @Service() class InjectedClass {} @Service() class ExampleClass { @Inject() injectedClass: InjectedClass; } /** Tokens must be explicity set in the Container with the desired value. */ Container.set(myToken, 'my-secret-value'); /** String identifier must be explicity set in the Container with the desired value. */ Container.set('my-dependency-name-A', InjectedClass); Container.set('my-dependency-name-B', 'primitive-value'); const injectedClassInstance = Container.get(InjectedClass); // a class without dependencies can be required const exampleClassInstance = Container.get(ExampleClass); // a class with dependencies can be required and dependencies will be resolved const tokenValue = Container.get(myToken); // tokenValue will be 'my-secret-value' const stringIdentifierValueA = Container.get('my-dependency-name-A'); // stringIdentifierValueA will be instance of InjectedClass const stringIdentifierValueB = Container.get('my-dependency-name-B'); // stringIdentifierValueB will be 'primitive-value' ``` -------------------------------- ### Basic TypeDI Service Injection Example in TypeScript Source: https://github.com/typestack/typedi/blob/develop/README.md This example demonstrates a fundamental use case of TypeDI for constructor-based dependency injection. Classes annotated with `@Service()` are registered with the container, allowing TypeDI to automatically inject instances of `ExampleInjectedService` into the constructor of `ExampleService` when requested via `Container.get(ExampleService)`. ```ts import { Container, Service } from 'typedi'; @Service() class ExampleInjectedService { printMessage() { console.log('I am alive!'); } } @Service() class ExampleService { constructor( // because we annotated ExampleInjectedService with the @Service() // decorator TypeDI will automatically inject an instance of // ExampleInjectedService here when the ExampleService class is requested // from TypeDI. public injectedService: ExampleInjectedService ) {} } const serviceInstance = Container.get(ExampleService); // we request an instance of ExampleService from TypeDI serviceInstance.injectedService.printMessage(); // logs "I am alive!" to the console ``` -------------------------------- ### Grouping Multiple Services with Tokens (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This example demonstrates how to group multiple service implementations under a single identifier using a `Token` and the `multiple: true` option in the `@Service()` decorator. It defines an interface, a token, and several factory implementations, then shows how to retrieve all grouped services as an array using `Container.getMany()`. ```TypeScript export interface Factory { create(): any; } export const FactoryToken = new Token('factories'); @Service({ id: FactoryToken, multiple: true }) export class BeanFactory implements Factory { create() { console.log('bean created'); } } @Service({ id: FactoryToken, multiple: true }) export class SugarFactory implements Factory { create() { console.log('sugar created'); } } @Service({ id: FactoryToken, multiple: true }) export class WaterFactory implements Factory { create() { console.log('water created'); } } Container.import([BeanFactory, SugarFactory, WaterFactory]); const factories = Container.getMany(FactoryToken); factories.forEach(factory => factory.create()); ``` -------------------------------- ### Defining Global Services Across All Containers (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This example demonstrates how to declare a service as global using `@Service({ global: true })`. A global service ensures that a single instance of that service is shared and reused across all containers, including scoped ones, providing a consistent instance regardless of the context. ```TypeScript @Service({ global: true }) export class QuestionUtils {} ``` -------------------------------- ### Creating Services with Factory Classes in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This example demonstrates using a dedicated factory class (CarFactory) to create service instances. The CarFactory itself is a service, allowing it to have its own dependencies (e.g., LoggerService). The Car service is then configured to use a specific method (create) of the CarFactory to produce its instances, providing more complex and dependency-aware service creation logic. ```typescript import { Container, Service } from 'typedi'; @Service() class CarFactory { constructor(public logger: LoggerService) {} create() { return new Car('BMW', this.logger); } } @Service({ factory: [CarFactory, 'create'] }) class Car { constructor(public model: string, public logger: LoggerInterface) {} } ``` -------------------------------- ### Using Named Services with TypeDI in TypeScript Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This example demonstrates how to define and use named services in TypeDI. It shows how to register multiple Factory implementations with unique IDs and then inject them into a CoffeeMaker class using the @Inject decorator, both for property and constructor injection. This pattern is useful for managing different implementations of an interface or specific configurations. ```typescript import { Container, Service, Inject } from 'typedi'; interface Factory { create(): void; } @Service({ id: 'bean.factory' }) class BeanFactory implements Factory { create() {} } @Service({ id: 'sugar.factory' }) class SugarFactory implements Factory { create() {} } @Service({ id: 'water.factory' }) class WaterFactory implements Factory { create() {} } @Service({ id: 'coffee.maker' }) class CoffeeMaker { beanFactory: Factory; sugarFactory: Factory; @Inject('water.factory') waterFactory: Factory; constructor(@Inject('bean.factory') beanFactory: BeanFactory, @Inject('sugar.factory') sugarFactory: SugarFactory) { this.beanFactory = beanFactory; this.sugarFactory = sugarFactory; } make() { this.beanFactory.create(); this.sugarFactory.create(); this.waterFactory.create(); } } let coffeeMaker = Container.get('coffee.maker'); coffeeMaker.make(); ``` -------------------------------- ### Creating Services with Factory Functions in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet shows how to register a service with TypeDI using a factory function. Instead of direct class instantiation, the createCar function is called to produce the Car instance. This allows for custom instantiation logic, such as passing specific constructor arguments or performing setup before the service is returned by the container. ```typescript import { Container, Service } from 'typedi'; function createCar() { return new Car('V8'); } @Service({ factory: createCar }) class Car { constructor(public engineType: string) {} } // Getting service from the container. // Service will be created by calling the specified factory function. const car = Container.get(Car); console.log(car.engineType); // > "V8" ``` -------------------------------- ### Mocking Dependencies for Testing with TypeDI in TypeScript Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This example demonstrates how to replace real service implementations with 'fake' dependencies for testing purposes using Container.set. It shows how to set a mock instance for a class-based service (CoffeeMaker) and also how to provide multiple named service mocks (bean.factory, sugar.factory, water.factory) using an array of objects, facilitating isolated unit testing. ```typescript Container.set(CoffeeMaker, new FakeCoffeeMaker()); // or for named services Container.set([ { id: 'bean.factory', value: new FakeBeanFactory() }, { id: 'sugar.factory', value: new FakeSugarFactory() }, { id: 'water.factory', value: new FakeWaterFactory() }, ]); ``` -------------------------------- ### Injecting Dependencies via Constructor in TypeDI Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/02-basic-usage-guide.md This example illustrates automatic dependency injection through class constructors. When a class annotated with `@Service()` is resolved by TypeDI, its constructor parameters, if they are also `@Service()` annotated classes, are automatically provided with their respective instances. The container instance itself is also injected as the last parameter. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedClass {} @Service() class ExampleClass { constructor(public injectedClass: InjectedClass) {} } const instance = Container.get(ExampleClass); console.log(instance.injectedClass instanceof InjectedClass); // prints true as TypeDI assigned the instance of InjectedClass to the property ``` -------------------------------- ### Defining a Transient Service in TypeDI Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/02-basic-usage-guide.md This snippet demonstrates how to define a class as 'transient' in TypeDI using the `@Service({ scope: 'transient' })` decorator. When a class is marked as transient, each call to `Container.get()` for that class will return a new, distinct instance, as opposed to the default singleton behavior. The example shows that `instanceA` and `instanceB` are different objects. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service({ scope: 'transient' }) class ExampleTransientClass { constructor() { console.log('I am being created!'); // this line will be printed twice } } const instanceA = Container.get(ExampleTransientClass); const instanceB = Container.get(ExampleTransientClass); console.log(instanceA !== instanceB); // prints true ``` -------------------------------- ### Using Named Services for Dependency Injection with TypeDI in JavaScript Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/02-basic-usage.md This example illustrates how to use named services with TypeDI. Instead of injecting classes directly, services are registered with string identifiers using Container.set(). The CoffeeMaker then retrieves these dependencies by their names (e.g., 'bean.factory') via container.get(). This approach provides more flexibility for managing and resolving dependencies. ```javascript var Container = require('typedi').Container; class BeanFactory implements Factory { create() {} } class SugarFactory implements Factory { create() {} } class WaterFactory implements Factory { create() {} } class CoffeeMaker { beanFactory: Factory; sugarFactory: Factory; waterFactory: Factory; constructor(container) { this.beanFactory = container.get('bean.factory'); this.sugarFactory = container.get('sugar.factory'); this.waterFactory = container.get('water.factory'); } make() { this.beanFactory.create(); this.sugarFactory.create(); this.waterFactory.create(); } } Container.set('bean.factory', new BeanFactory(Container)); Container.set('sugar.factory', new SugarFactory(Container)); Container.set('water.factory', new WaterFactory(Container)); Container.set('coffee.maker', new CoffeeMaker(Container)); var coffeeMaker = Container.get('coffee.maker'); coffeeMaker.make(); ``` -------------------------------- ### Overriding Dependencies for Testing with TypeDI in JavaScript Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/02-basic-usage.md This example shows how TypeDI facilitates testing by allowing easy replacement of real dependencies with 'fake' or mock implementations. You can override a class-based service by calling Container.set() with the class and a new instance, or override multiple named services by providing an array of objects with id and value properties. This enables isolated unit testing of components. ```javascript Container.set(CoffeeMaker, new FakeCoffeeMaker()); // or for named services Container.set([ { id: 'bean.factory', value: new FakeBeanFactory() }, { id: 'sugar.factory', value: new FakeSugarFactory() }, { id: 'water.factory', value: new FakeWaterFactory() } ]); ``` -------------------------------- ### Explicit Type Request with @Inject in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/05-inject-decorator.md This snippet demonstrates how to explicitly specify the target type for injection using `@Inject` when automatic inference is not desired or possible (e.g., for interfaces). It shows examples of overriding inferred types for both property and constructor injection using a constructable value (class definition). ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedExampleClass { print() { console.log('I am alive!'); } } @Service() class BetterInjectedClass { print() { console.log('I am a different class!'); } } @Service() class ExampleClass { @Inject() inferredPropertyInjection: InjectedExampleClass; /** * We tell TypeDI that initialize the `BetterInjectedClass` class * regardless of what is the inferred type. */ @Inject(() => BetterInjectedClass) explicitPropertyInjection: InjectedExampleClass; constructor( public inferredArgumentInjection: InjectedExampleClass, /** * We tell TypeDI that initialize the `BetterInjectedClass` class * regardless of what is the inferred type. */ @Inject(() => BetterInjectedClass) public explicitArgumentInjection: InjectedExampleClass ) {} } /** * The `instance` variable is an ExampleClass instance with both the * - `inferredPropertyInjection` and `inferredArgumentInjection` property * containing an `InjectedExampleClass` instance * - `explicitPropertyInjection` and `explicitArgumentInjection` property * containing a `BetterInjectedClass` instance. */ const instance = Container.get(ExampleClass); instance.inferredPropertyInjection.print(); // prints "I am alive!" (InjectedExampleClass.print function) instance.explicitPropertyInjection.print(); // prints "I am a different class!" (BetterInjectedClass.print function) instance.inferredArgumentInjection.print(); // prints "I am alive!" (InjectedExampleClass.print function) instance.explicitArgumentInjection.print(); // prints "I am a different class!" (BetterInjectedClass.print function) ``` -------------------------------- ### Injecting TypeDI Service Tokens with @Inject Decorator (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/06-service-tokens.md This example illustrates how to inject a value associated with a `Token` into a class property using the `@Inject()` decorator in TypeDI. It shows how the container automatically resolves the token's value and assigns it to the decorated property, providing a clean way to inject specific dependencies. ```TypeScript import 'reflect-metadata'; import { Container, Token, Inject, Service } from 'typedi'; export const JWT_SECRET_TOKEN = new Token('MY_SECRET'); Container.set(JWT_SECRET_TOKEN, 'wow-such-secure-much-encryption'); @Service() class Example { @Inject(JWT_SECRET_TOKEN) myProp: string; } const instance = Container.get(Example); // The instance.myProp property has the value assigned for the Token ``` -------------------------------- ### Implementing Custom Decorator for Dependency Injection in TypeDI Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/08-custom-decorators.md This comprehensive example demonstrates how to create a custom `@Logger()` decorator in TypeDI. It involves defining the decorator function, an interface for the logger, a concrete logger implementation, and finally, using the decorator in a service class's constructor to inject the logger instance. The `Container.registerHandler` is used within the decorator to provide the value. ```TypeScript // Logger.ts export function Logger() { return function (object: Object, propertyName: string, index?: number) { const logger = new ConsoleLogger(); Container.registerHandler({ object, propertyName, index, value: containerInstance => logger }); }; } ``` ```TypeScript // LoggerInterface.ts export interface LoggerInterface { log(message: string): void; } ``` ```TypeScript // ConsoleLogger.ts import { LoggerInterface } from './LoggerInterface'; export class ConsoleLogger implements LoggerInterface { log(message: string) { console.log(message); } } ``` ```TypeScript // UserRepository.ts @Service() export class UserRepository { constructor(@Logger() private logger: LoggerInterface) {} save(user: User) { this.logger.log(`user ${user.firstName} ${user.secondName} has been saved.`); } } ``` -------------------------------- ### Registering Dependencies with TypeDI Container Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/02-basic-usage-guide.md This snippet demonstrates how to register values using TypeDI's `Container.set()` method with both `Token`s and string identifiers. It also shows how to retrieve these registered values later using `Container.get()`, illustrating the basic mechanism for managing non-class dependencies or specific configurations. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service, Token } from 'typedi'; const myToken = new Token('SECRET_VALUE_KEY'); Container.set(myToken, 'my-secret-value'); Container.set('my-config-key', 'value-for-config-key'); Container.set('default-pagination', 30); // somewhere else in your application const tokenValue = Container.get(myToken); const configValue = Container.get('my-config-key'); const defaultPagination = Container.get('default-pagination'); ``` -------------------------------- ### Implementing Function-Based Dependency Injection (JavaScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet showcases an alternative approach to defining services using functions instead of classes, enabling functional dependency injection. It demonstrates how to define services that return objects and how to inject multiple dependencies into a functional service, then retrieve and use the composed service. ```JavaScript export const PostRepository = Service(() => ({ getName() { return 'hello from post repository'; }, })); export const PostManager = Service(() => ({ getId() { return 'some post id'; }, })); export class PostQueryBuilder { build() { return 'SUPER * QUERY'; } } export const PostController = Service( [PostManager, PostRepository, PostQueryBuilder], (manager, repository, queryBuilder) => { return { id: manager.getId(), name: repository.getName(), query: queryBuilder.build(), }; } ); const postController = Container.get(PostController); console.log(postController); ``` -------------------------------- ### Managing Scoped Service Instances with Multiple Containers (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet illustrates the use of `Container.of()` to create and manage distinct, scoped instances of services based on a unique context identifier (e.g., a request object). It shows how `QuestionController` and its dependency `QuestionRepository` are instantiated uniquely for different request contexts, and how `Container.reset()` clears a specific scoped container. ```TypeScript @Service() export class QuestionController { constructor(protected questionRepository: QuestionRepository) {} save() { this.questionRepository.save(); } } @Service() export class QuestionRepository { save() {} } const request1 = { param: 'question1' }; const controller1 = Container.of(request1).get(QuestionController); controller1.save('Timber'); Container.reset(request1); const request2 = { param: 'question2' }; const controller2 = Container.of(request2).get(QuestionController); controller2.save(''); Container.reset(request2); ``` -------------------------------- ### Injecting Configuration Options with TypeDI in TypeScript Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet illustrates how to store and inject global application parameters or configuration options using TypeDI's Container.set method. It registers an 'authorization-token' string and then injects it into a UserRepository class using the @Inject decorator, making global settings easily accessible within services. ```typescript import { Container, Service, Inject } from 'typedi'; // somewhere in your global app parameters Container.set('authorization-token', 'RVT9rVjSVN'); @Service() class UserRepository { @Inject('authorization-token') authorizationToken: string; } ``` -------------------------------- ### Creating Custom Decorators for Dependency Injection (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet illustrates how to define and use a custom decorator, `@Logger()`, to inject a specific dependency (`LoggerInterface`) into a service's constructor. It shows the decorator's implementation, the interface, a concrete logger class, and its application in a `UserRepository` for logging user save operations. ```TypeScript export function Logger() { return function (object: Object, propertyName: string, index?: number) { const logger = new ConsoleLogger(); Container.registerHandler({ object, propertyName, index, value: containerInstance => logger }); }; } export interface LoggerInterface { log(message: string): void; } import { LoggerInterface } from './LoggerInterface'; export class ConsoleLogger implements LoggerInterface { log(message: string) { console.log(message); } } @Service() export class UserRepository { constructor(@Logger() private logger: LoggerInterface) {} save(user: User) { this.logger.log(`user ${user.firstName} ${user.secondName} has been saved.`); } } ``` -------------------------------- ### Basic Class-based Dependency Injection with TypeDI in JavaScript Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/02-basic-usage.md This snippet demonstrates basic dependency injection using TypeDI in JavaScript without TypeScript. It shows how to define classes (BeanFactory, SugarFactory, WaterFactory) and inject them into a CoffeeMaker class's constructor using the container.get() method. The Container instance is passed as the last argument to the constructor, allowing the CoffeeMaker to resolve its dependencies at runtime. ```javascript class BeanFactory { create() {} } class SugarFactory { create() {} } class WaterFactory { create() {} } class CoffeeMaker { constructor(container) { this.beanFactory = container.get(BeanFactory); this.sugarFactory = container.get(SugarFactory); this.waterFactory = container.get(WaterFactory); } make() { this.beanFactory.create(); this.sugarFactory.create(); this.waterFactory.create(); } } var Container = require('typedi').Container; var coffeeMaker = Container.get(CoffeeMaker); coffeeMaker.make(); ``` -------------------------------- ### Configuring TypeDI Container for routing-controllers and TypeORM (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/07-usage-with-typeorm.md This snippet demonstrates how to configure `routing-controllers` and `TypeORM` to use the same top-level TypeDI container. It imports the `useContainer` functions from both libraries and the `Container` class from `typedi`, then passes the `Container` instance to each `useContainer` function to establish the dependency injection integration. ```TypeScript import { useContainer as rcUseContainer } from 'routing-controllers'; import { useContainer as typeOrmUseContainer } from 'typeorm'; import { Container } from 'typedi'; rcUseContainer(Container); typeOrmUseContainer(Container); ``` -------------------------------- ### Configuring TypeScript for Decorator Metadata Emission Source: https://github.com/typestack/typedi/blob/develop/README.md These two compiler options, `emitDecoratorMetadata` and `experimentalDecorators`, must be enabled in your `tsconfig.json` file under the `compilerOptions` key. `emitDecoratorMetadata` allows the TypeScript compiler to emit design-time type metadata for decorators, which TypeDI uses for dependency resolution, while `experimentalDecorators` enables the use of ES7 decorators. ```json "emitDecoratorMetadata": true, "experimentalDecorators": true, ``` -------------------------------- ### Injecting Configuration Options as Named Services with TypeDI in JavaScript Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/02-basic-usage.md This snippet demonstrates how TypeDI can be used to store and inject global settings or configuration options. A string value, like an authorization token, is registered with the container using a named ID ('authorization-token'). Classes like UserRepository can then easily retrieve this configuration value from the container in their constructors, promoting a clean separation of concerns. ```javascript var Container = require('typedi').Container; // somewhere in your global app parameters Container.set('authorization-token', 'RVT9rVjSVN'); class UserRepository { constructor(container) { this.authorizationToken = container.get('authorization-token'); } } ``` -------------------------------- ### Function-based Dependency Injection with TypeDI in JavaScript Source: https://github.com/typestack/typedi/blob/develop/docs/javascript/02-basic-usage.md This snippet demonstrates TypeDI's support for function-based dependency injection. Services can be defined as functions wrapped by Service(), returning an object with methods. For PostController, an array of dependencies (PostManager, PostRepository, PostQueryBuilder) is provided, and the Service decorator injects them as arguments into the factory function, allowing for flexible service creation. ```javascript var Service = require('typedi').Service; var Container = require('typedi').Container; var PostRepository = Service(() => ({ getName() { return 'hello from post repository'; } })); var PostManager = Service(() => ({ getId() { return 'some post id'; } })); class PostQueryBuilder { build() { return 'SUPER * QUERY'; } } var PostController = Service([PostManager, PostRepository, PostQueryBuilder], (manager, repository, queryBuilder) => { return { id: manager.getId(), name: repository.getName(), query: queryBuilder.build() }; }); var postController = Container.get(PostController); console.log(postController); ``` -------------------------------- ### Importing Reflect-Metadata in TypeScript Application Source: https://github.com/typestack/typedi/blob/develop/README.md This line imports the `reflect-metadata` package. It is critical that this import is the very first line in your application's entry file to ensure that decorator metadata is available globally before any TypeDI services are defined or utilized. ```ts import 'reflect-metadata'; // Your other imports and initialization code // comes here after you imported the reflect-metadata package! ``` -------------------------------- ### Demonstrating Property Inheritance with TypeDI Services Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/07-inheritance.md This snippet illustrates how TypeDI supports property inheritance. It defines a BaseClass with an injected dependency (InjectedClass) and an ExtendedClass that inherits from BaseClass. Both base and extended classes are marked with @Service(), ensuring that injectedClass is correctly resolved and available in the ExtendedClass instance. ```typescript import 'reflect-metadata'; import { Container, Token, Inject, Service } from 'typedi'; @Service() class InjectedClass { name: string = 'InjectedClass'; } @Service() class BaseClass { name: string = 'BaseClass'; @Inject() injectedClass: InjectedClass; } @Service() class ExtendedClass extends BaseClass { name: string = 'ExtendedClass'; } const instance = Container.get(ExtendedClass); // instance has the `name` property with "ExtendedClass" value (overwritten the base class) // and the `injectedClass` property with the instance of the `InjectedClass` class console.log(instance.injectedClass.name); // logs "InjectedClass" console.log(instance.name); // logs "ExtendedClass" ``` -------------------------------- ### Creating and Retrieving TypeDI Service Tokens (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/06-service-tokens.md This snippet demonstrates how to create a type-safe `Token` in TypeDI, set a value for it in the `Container`, and then retrieve that value. The `Token` ensures type safety when accessing the stored value, preventing runtime errors from mistyped identifiers. ```TypeScript import 'reflect-metadata'; import { Container, Token } from 'typedi'; export const JWT_SECRET_TOKEN = new Token('MY_SECRET'); Container.set(JWT_SECRET_TOKEN, 'wow-such-secure-much-encryption'); /** * Somewhere else in the application after the JWT_SECRET_TOKEN is * imported in can be used to request the secret from the Container. * * This value is type-safe also because the Token is typed. */ const JWT_SECRET = Container.get(JWT_SECRET_TOKEN); ``` -------------------------------- ### Demonstrating Circular Reference Issue in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet illustrates a common problem with circular dependencies where Car injects Engine and Engine injects Car. Without a specific type resolution mechanism, one of the injected properties will be undefined due to the order of instantiation, leading to runtime errors. This code demonstrates the problematic pattern before its resolution. ```typescript // Car.ts @Service() export class Car { @Inject() engine: Engine; } // Engine.ts @Service() export class Engine { @Inject() car: Car; } ``` -------------------------------- ### Injecting Dependencies via Properties with @Inject Decorator Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/02-basic-usage-guide.md This snippet demonstrates how to inject dependencies directly into class properties using the `@Inject()` decorator. When the parent class (annotated with `@Service()`) is initialized by TypeDI, any property marked with `@Inject()` will automatically receive an instance of its declared type. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedClass {} @Service() class ExampleClass { @Inject() injectedClass: InjectedClass; } const instance = Container.get(ExampleClass); console.log(instance.injectedClass instanceof InjectedClass); // prints true as the instance of InjectedClass has been assigned to the `injectedClass` property by TypeDI ``` -------------------------------- ### Demonstrating Uniqueness of TypeDI Tokens with Same Name (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/06-service-tokens.md This snippet clarifies that TypeDI `Token` instances are unique even if they are created with the same descriptive name. It shows that setting and retrieving values for two distinct `Token` objects, despite having identical names, results in different stored values, emphasizing their unique identity. ```TypeScript import 'reflect-metadata'; import { Container, Token } from 'typedi'; const tokenA = new Token('TOKEN'); const tokenB = new Token('TOKEN'); Container.set(tokenA, 'value-A'); Container.set(tokenB, 'value-B'); const tokenValueA = Container.get(tokenA); // tokenValueA is "value-A" const tokenValueB = Container.get(tokenB); // tokenValueB is "value-B" console.log(tokenValueA === tokenValueB); // returns false, as Tokens are always unique ``` -------------------------------- ### Property Injection with @Inject in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/05-inject-decorator.md This snippet demonstrates property injection using the `@Inject` decorator in TypeDI. It shows how `@Inject` is mandatory for properties to be resolved, while properties without it remain undefined. It illustrates automatic type inference for class properties. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedExampleClass { print() { console.log('I am alive!'); } } @Service() class ExampleClass { @Inject() withDecorator: InjectedExampleClass; withoutDecorator: InjectedExampleClass; } const instance = Container.get(ExampleClass); /** * The `instance` variable is an ExampleClass instance with the `withDecorator` * property containing an InjectedExampleClass instance and `withoutDecorator` * property being undefined. */ console.log(instance); instance.withDecorator.print(); // prints "I am alive!" (InjectedExampleClass.print function) console.log(instance.withoutDecorator); // logs undefined, as this property was not marked with an @Inject decorator ``` -------------------------------- ### Resolving Circular References in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/README.md This snippet provides the solution for circular dependencies in TypeDI by using a type-resolving function within the @Inject decorator. By wrapping the injected type in a type => Type function, TypeDI can defer the type resolution until both services are fully defined, preventing undefined injection issues. This fix applies to property injections but not constructor injections. ```typescript // Car.ts @Service() export class Car { @Inject(type => Engine) engine: Engine; } // Engine.ts @Service() export class Engine { @Inject(type => Car) car: Car; } ``` -------------------------------- ### Constructor Injection with @Inject in TypeDI (TypeScript) Source: https://github.com/typestack/typedi/blob/develop/docs/typescript/05-inject-decorator.md This snippet illustrates constructor injection in TypeDI. It highlights that the `@Inject` decorator is not strictly required for constructor parameters when the class is marked with `@Service`, as TypeDI automatically infers and injects types. It also shows how `@Inject` can be used to explicitly overwrite the injected type. ```TypeScript import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedExampleClass { print() { console.log('I am alive!'); } } @Service() class ExampleClass { constructor( @Inject() public withDecorator: InjectedExampleClass, public withoutDecorator: InjectedExampleClass ) {} } const instance = Container.get(ExampleClass); /** * The `instance` variable is an ExampleClass instance with both the * `withDecorator` and `withoutDecorator` property containing an * InjectedExampleClass instance. */ console.log(instance); instance.withDecorator.print(); // prints "I am alive!" (InjectedExampleClass.print function) instance.withoutDecorator.print(); // prints "I am alive!" (InjectedExampleClass.print function) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.