### Install and Configure TSyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Instructions for installing the package via npm or yarn and configuring the necessary TypeScript compiler options for decorators. ```bash npm install --save tsyringe ``` ```bash yarn add tsyringe ``` ```json { "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } } ``` -------------------------------- ### Install and Configure TSyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Instructions for installing the package via npm or yarn and configuring the necessary TypeScript compiler options and Reflect metadata polyfill. ```bash npm install --save tsyringe yarn add tsyringe ``` ```json { "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } } ``` ```typescript import "reflect-metadata"; ``` -------------------------------- ### Install Babel Plugin for TypeScript Metadata Source: https://www.npmjs.com/package/tsyringe?activeTab=code Provides commands to install the 'babel-plugin-transform-typescript-metadata' package, necessary when using Babel for projects that rely on TypeScript decorator metadata. ```bash yarn add --dev babel-plugin-transform-typescript-metadata ``` ```bash npm install --save-dev babel-plugin-transform-typescript-metadata ``` -------------------------------- ### Install tsyringe package Source: https://www.npmjs.com/package/tsyringe?activeTab=code Command to install the tsyringe package via npm. ```bash npm i tsyringe ``` -------------------------------- ### Configure Babel for Metadata Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies If using Babel, you must install and configure the transform-typescript-metadata plugin to ensure decorator metadata is preserved. ```bash yarn add --dev babel-plugin-transform-typescript-metadata ``` ```bash npm install --save-dev babel-plugin-transform-typescript-metadata ``` ```javascript plugins: [ 'babel-plugin-transform-typescript-metadata' ] ``` -------------------------------- ### Install TSyringe using npm or yarn Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Instructions for installing the TSyringe package using either npm or yarn package managers. This is the first step to integrating TSyringe into your project. ```bash npm install --save tsyringe ``` ```bash yarn add tsyringe ``` -------------------------------- ### Configure Babel for TypeScript Metadata Source: https://www.npmjs.com/package/tsyringe?activeTab=readme If using Babel, install and configure the `babel-plugin-transform-typescript-metadata` plugin to ensure TypeScript metadata is emitted for TSyringe to use. ```bash yarn add --dev babel-plugin-transform-typescript-metadata ``` ```bash npm install --save-dev babel-plugin-transform-typescript-metadata ``` ```javascript plugins: [ 'babel-plugin-transform-typescript-metadata', /* ...the rest of your config... */ ] ``` -------------------------------- ### Test Setup for Clearing Instances with Tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Illustrates how to use `clearInstances()` within a `beforeEach` block for testing. This ensures that singleton instances are fresh for each test, preventing state leakage between tests. ```typescript @singleton() class Foo {} beforeEach(() => { container.clearInstances(); }); test("something", () => { container.resolve(Foo); // will be a new singleton instance in every test }); ``` -------------------------------- ### Instance Caching Factory Example Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Provides an example of using `instanceCachingFactory` to create a factory that lazily constructs and caches an object, ensuring a single instance is returned for each resolution. ```typescript import {instanceCachingFactory} from "tsyringe"; { token: "SingletonFoo"; useFactory: instanceCachingFactory(c => c.resolve(Foo)); } ``` -------------------------------- ### Inject and InjectAll Decorators Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Demonstrates how to use @inject for interface/token-based injection and @injectAll for injecting arrays of dependencies. ```typescript import {injectable, inject, injectAll} from "tsyringe"; @injectable() class Foo { constructor(@inject("Database", { isOptional: true }) private database?: Database) {} } @injectable() class Bar { constructor(@injectAll(Foo) fooArray: Foo[]) {} } ``` -------------------------------- ### Resolve Dependencies Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Covers basic resolution of single instances using resolve() and multiple instances using resolveAll(), including how to register multiple classes against a single token. ```typescript const myFoo = container.resolve(Foo); const myBar = container.resolve("Bar"); // Resolving all instances const myBars = container.resolveAll("Bar"); // Injectable decorator token registration @injectable({token: "Bar"}) class Foo implements Bar {} ``` -------------------------------- ### Resolving Dependencies Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Illustrates how to resolve instances from a container using `resolve()` for a single instance and `resolveAll()` for all registered instances of a given token. Handles recursive dependency fulfillment. ```typescript const myFoo = container.resolve(Foo); const myBar = container.resolve("Bar"); ``` ```typescript interface Bar {} @injectable() class Foo implements Bar {} @injectable() class Baz implements Bar {} @registry([ // registry is optional, all you need is to use the same token when registering {token: "Bar", useToken: Foo}, // can be any provider {token: "Bar", useToken: Baz} ]) class MyRegistry {} const myBars = container.resolveAll("Bar"); // myBars type is Bar[] ``` -------------------------------- ### Use @injectable() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Decorate classes with `@injectable()` to allow TSyringe to inject their dependencies at runtime. This example shows injecting a `Database` dependency into a `Foo` class. ```typescript import {injectable} from "tsyringe"; @injectable() class Foo { constructor(private database: Database) {} } // some other file import "reflect-metadata"; import {container} from "tsyringe"; import {Foo} from "./foo"; const instance = container.resolve(Foo); ``` -------------------------------- ### Resolve Dependencies from Container Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Shows how to retrieve instances from the container using resolve() and resolveAll(). It also demonstrates how to register multiple instances against a single token. ```typescript const myFoo = container.resolve(Foo); const myBar = container.resolve("Bar"); // Resolving all instances for a token const myBars = container.resolveAll("Bar"); ``` -------------------------------- ### Use injectAll() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Injects an array of resolved instances based on a provided injection token. ```typescript import {injectable, injectAll} from "tsyringe"; @injectable() class Bar { constructor(@injectAll(Foo) fooArray: Foo[]) { // ... } } ``` -------------------------------- ### Resolve Dependencies from Container Source: https://www.npmjs.com/package/tsyringe Covers the process of resolving tokens into instances using resolve() for single instances and resolveAll() for multiple instances registered under the same token. ```typescript const myFoo = container.resolve(Foo); const myBar = container.resolve("Bar"); // Resolving all instances for a token const myBars = container.resolveAll("Bar"); // Resolving via @injectable token configuration @injectable({token: "Bar"}) class Foo implements Bar {} ``` -------------------------------- ### Use singleton() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Registers a class as a singleton, ensuring that the same instance is returned every time it is resolved from the container. ```typescript import {singleton, container} from "tsyringe"; import "reflect-metadata"; @singleton() class Foo { constructor() {} } const instance = container.resolve(Foo); ``` -------------------------------- ### Check Registration Status Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Demonstrates how to verify if a token is registered within a container, including recursive checks for parent containers. ```typescript const isRegistered = container.isRegistered("Bar"); // Recursive check in child container childContainer.isRegistered(Bar, true); ``` -------------------------------- ### Check Registration Status Source: https://www.npmjs.com/package/tsyringe Demonstrates how to verify if a token is registered within a container, including recursive checks for child containers. ```typescript const isRegistered = container.isRegistered("Bar"); // true // Recursive check in parent container const childContainer = container.createChildContainer(); childContainer.isRegistered(Bar, true); // true ``` -------------------------------- ### Resolve dependencies with interfaces Source: https://www.npmjs.com/package/tsyringe?activeTab=code Demonstrates how to resolve interfaces by using the @inject decorator and registering the implementation class with the container. ```typescript // SuperService.ts export interface SuperService {} // TestService.ts import {SuperService} from "./SuperService"; export class TestService implements SuperService {} // Client.ts import {injectable, inject} from "tsyringe"; @injectable() export class Client { constructor(@inject("SuperService") private service: SuperService) {} } // main.ts import "reflect-metadata"; import {Client} from "./Client"; import {TestService} from "./TestService"; import {container} from "tsyringe"; container.register("SuperService", { useClass: TestService }); const client = container.resolve(Client); ``` -------------------------------- ### Transforming Injected Dependencies Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Shows how to use @injectWithTransform and @injectAllWithTransform to process or map dependencies before they are injected into a class constructor. ```typescript class FeatureFlags { public getFlagValue(flagName: string): boolean { // ... } } class Foo() {} class FeatureFlagsTransformer implements Transform { public transform(flags: FeatureFlags, flag: string) { return flags.getFlagValue(flag); } } @injectable() class MyComponent(foo: Foo, @injectWithTransform(FeatureFlags, FeatureFlagsTransformer, "IsBlahEnabled") blahEnabled: boolean){ // ... } @injectable() class Foo { public value; } class FooTransform implements Transform{ public transform(foos: Foo[]): string[]{ return foos.map(f => f.value); } } @injectable() class Bar { constructor(@injectAllWithTransform(Foo, FooTransform) stringArray: string[]) { // ... } } ``` -------------------------------- ### Dispose container instances Source: https://www.npmjs.com/package/tsyringe?activeTab=code Demonstrates how to dispose of instances created by the container. Supports both synchronous and asynchronous disposal patterns. ```typescript container.dispose(); await container.dispose(); ``` -------------------------------- ### Initialize Reflect Metadata Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies The Reflect polyfill is required for TSyringe to read metadata. It must be imported once at the entry point of the application. ```typescript import "reflect-metadata"; ``` -------------------------------- ### Registering Before Resolution Callback with Tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Demonstrates how to use `beforeResolution` to execute a callback function before a token is resolved. This is useful for performing actions like logging or validation prior to object instantiation. The callback receives the token and resolution type. ```typescript class Bar {} container.beforeResolution( Bar, // Callback signature is (token: InjectionToken, resolutionType: ResolutionType) => void () => { console.log("Bar is about to be resolved!"); }, {frequency: "Always"} ); ``` -------------------------------- ### Injectable and Singleton Decorators Source: https://www.npmjs.com/package/tsyringe Usage of @injectable and @singleton decorators to register classes for dependency injection or as singletons. ```typescript import {injectable, singleton, container} from "tsyringe"; import "reflect-metadata"; @injectable() class Foo { constructor(private database: Database) {} } @singleton() class Bar {} const instance = container.resolve(Foo); ``` -------------------------------- ### Use inject() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Allows injecting specific tokens or interfaces into constructor parameters. Supports optional injection via configuration. ```typescript import {injectable, inject} from "tsyringe"; @injectable() class Foo { constructor(@inject("Database") private database?: Database) {} } // Optional injection example @injectable() class Bar { constructor(@inject("Database", { isOptional: true }) private database?: Database) {} } ``` -------------------------------- ### Parameter Injection Decorators Source: https://www.npmjs.com/package/tsyringe Using @inject and @injectAll to resolve dependencies for interfaces or specific tokens, including optional injection support. ```typescript import {injectable, inject, injectAll} from "tsyringe"; @injectable() class Foo { constructor(@inject("Database") private database?: Database) {} } @injectable() class Bar { constructor(@injectAll(Foo) fooArray: Foo[]) {} } ``` -------------------------------- ### Transforming Injected Dependencies Source: https://www.npmjs.com/package/tsyringe?activeTab=code Shows how to use @injectWithTransform and @injectAllWithTransform to process or map dependencies before they are injected into a class constructor. ```typescript class FeatureFlags { public getFlagValue(flagName: string): boolean { // ... } } class Foo() {} class FeatureFlagsTransformer implements Transform { public transform(flags: FeatureFlags, flag: string) { return flags.getFlagValue(flag); } } @injectable() class MyComponent(foo: Foo, @injectWithTransform(FeatureFlags, FeatureFlagsTransformer, "IsBlahEnabled") blahEnabled: boolean){ // ... } ``` ```typescript @injectable() class Foo { public value; } class FooTransform implements Transform{ public transform(foos: Foo[]): string[]{ return foos.map(f => f.value)); } } @injectable() class Bar { constructor(@injectAllWithTransform(Foo, FooTransform) stringArray: string[]) { // ... } } ``` -------------------------------- ### Transforming Resolved Dependencies Source: https://www.npmjs.com/package/tsyringe?activeTab=versions Shows how to use @injectWithTransform and @injectAllWithTransform to process or map dependencies before they are injected into a class constructor. ```typescript class FeatureFlagsTransformer implements Transform { public transform(flags: FeatureFlags, flag: string) { return flags.getFlagValue(flag); } } @injectable() class MyComponent(foo: Foo, @injectWithTransform(FeatureFlags, FeatureFlagsTransformer, "IsBlahEnabled") blahEnabled: boolean){} class FooTransform implements Transform{ public transform(foos: Foo[]): string[]{ return foos.map(f => f.value); } } @injectable() class Bar { constructor(@injectAllWithTransform(Foo, FooTransform) stringArray: string[]) {} } ``` -------------------------------- ### Dispose Container Instances (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Demonstrates how to dispose of all instances created by the container that implement the `Disposable` interface. This can be done synchronously or asynchronously. ```typescript import { container } from "tsyringe"; // Synchronous disposal container.dispose(); // Asynchronous disposal await container.dispose(); ``` -------------------------------- ### Resolve classes without interfaces Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Shows how to resolve dependencies using runtime type information. This approach requires no extra configuration as the container inspects class metadata. ```TypeScript // Foo.ts export class Foo {} // Bar.ts import {Foo} from "./Foo"; import {injectable} from "tsyringe"; @injectable() export class Bar { constructor(public myFoo: Foo) {} } // main.ts import "reflect-metadata"; import {container} from "tsyringe"; import {Bar} from "./Bar"; const myBar = container.resolve(Bar); ``` -------------------------------- ### Dispose container instances Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Demonstrates how to trigger the disposal of all objects implementing the Disposable interface within a tsyringe container. Supports both synchronous and asynchronous disposal patterns. ```TypeScript container.dispose(); // Or for asynchronous disposal: await container.dispose(); ``` -------------------------------- ### Inject primitive values Source: https://www.npmjs.com/package/tsyringe Demonstrates how to inject non-class values like strings or numbers into constructors using named injection tokens. ```typescript import {singleton, inject} from "tsyringe"; @singleton() class Foo { private str: string; constructor(@inject("SpecialString") value: string) { this.str = value; } } // Registration import "reflect-metadata"; import {container} from "tsyringe"; const str = "test"; container.register("SpecialString", {useValue: str}); const instance = container.resolve(Foo); ``` -------------------------------- ### Add Reflect API Polyfill Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Import a Reflect API polyfill, such as `reflect-metadata`, once in your application's entry point before using TSyringe's dependency injection features. ```typescript // main.ts import "reflect-metadata"; // Your code here... ``` -------------------------------- ### Register Dependencies in Container Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Demonstrates the standard approach to registering classes, values, or factories within a DependencyContainer before instantiation. ```typescript container.register(Foo, {useClass: Foo}); container.register(Bar, {useValue: new Bar()}); container.register("MyBaz", {useValue: new Baz()}); ``` -------------------------------- ### Checking Token Registration Status Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Demonstrates the `isRegistered()` method for checking if a token exists in the container. Includes an option to recursively check parent containers for the token's registration. ```typescript const isRegistered = container.isRegistered("Bar"); // true ``` ```typescript class Bar {} container.register(Bar, {useClass: Bar}); const childContainer = container.createChildContainer(); childContainer.isRegistered(Bar); // false childContainer.isRegistered(Bar, true); // true ``` -------------------------------- ### Inject primitive values via named injection Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Demonstrates how to inject non-class values like strings or numbers into constructors using named tokens. ```TypeScript import {singleton, inject} from "tsyringe"; @singleton() class Foo { private str: string; constructor(@inject("SpecialString") value: string) { this.str = value; } } import "reflect-metadata"; import {container} from "tsyringe"; const str = "test"; container.register("SpecialString", {useValue: str}); const instance = container.resolve(Foo); ``` -------------------------------- ### Using `delay` with Interfaces for Circular Dependencies in Tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Illustrates how to use the `delay` helper function with interfaces to manage circular dependencies. By using `delay` with `useToken` in the `@registry` decorator, tsyringe can transparently handle dependencies between classes that implement or depend on interfaces, even when they form a cycle. ```typescript export interface IFoo {} @injectable() @registry([ { token: "IBar", // `DelayedConstructor` of Bar will be the token useToken: delay(() => Bar) } ]) export class Foo implements IFoo { constructor(@inject("IBar") public bar: IBar) {} } export interface IBar {} @injectable() @registry([ { token: "IFoo", useToken: delay(() => Foo) } ]) export class Bar implements IBar { constructor(@inject("IFoo") public foo: IFoo) {} } ``` -------------------------------- ### Inject Primitive Values with Named Injection (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Demonstrates how to inject primitive values, such as strings, into a class using named injection. This involves registering the value with a specific token. ```typescript import { singleton, inject } from "tsyringe"; @singleton() class Foo { private str: string; constructor(@inject("SpecialString") value: string) { this.str = value; } } // some other file import "reflect-metadata"; import { container } from "tsyringe"; import { Foo } from "./foo"; const str = "test"; container.register("SpecialString", {useValue: str}); const instance = container.resolve(Foo); ``` -------------------------------- ### Class Provider Registration Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Shows the structure of a Class Provider, used for resolving classes by their constructor. It includes the `token` and `useClass` properties. ```typescript { token: InjectionToken; useClass: constructor; } ``` -------------------------------- ### Use autoInjectable() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Replaces a class constructor with one that automatically resolves dependencies from the global container, allowing for parameterless instantiation. ```typescript import {autoInjectable} from "tsyringe"; @autoInjectable() class Foo { constructor(private database?: Database) {} } const instance = new Foo(); ``` -------------------------------- ### Configure Babel for TypeScript Metadata Source: https://www.npmjs.com/package/tsyringe?activeTab=code Shows how to add the 'babel-plugin-transform-typescript-metadata' to your Babel configuration file to ensure TypeScript metadata is correctly processed. ```javascript plugins: [ 'babel-plugin-transform-typescript-metadata', /* ...the rest of your config... */ ] ``` -------------------------------- ### Resolving Circular Dependencies with `delay` in Tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Explains and demonstrates how to resolve circular dependencies between classes using the `delay` helper function. `delay` wraps a constructor, creating a proxy that defers the actual instantiation until the dependency is first accessed, thus breaking the circularity. ```typescript @injectable() export class Foo { constructor(public bar: Bar) {} } @injectable() export class Bar { constructor(public foo: Foo) {} } // container.resolve(Foo); ``` ```typescript @injectable() export class Foo { constructor(@inject(delay(() => Bar)) public bar: Bar) {} } @injectable() export class Bar { constructor(@inject(delay(() => Foo)) public foo: Foo) {} } // construction of foo is possible const foo = container.resolve(Foo); // property bar will hold a proxy that looks and acts as a real Bar instance. foo.bar instanceof Bar; // true ``` -------------------------------- ### Inject primitive values via named injection Source: https://www.npmjs.com/package/tsyringe?activeTab=versions Demonstrates how to inject non-class values like strings or numbers into constructors using named tokens and container registration. ```TypeScript @singleton() class Foo { constructor(@inject("SpecialString") value: string) {} } const str = "test"; container.register("SpecialString", {useValue: str}); const instance = container.resolve(Foo); ``` -------------------------------- ### Register Tokens via Injectable Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Demonstrates how to associate one or more InjectionTokens directly with a class using the @injectable decorator for easier resolution. ```typescript @injectable({token: "Bar"}) class Foo implements Bar {} @injectable({token: ["Bar", "Bar2"]}) class Baz implements Bar {} ``` -------------------------------- ### Injectable Decorator with Token Specification Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Shows how to specify injection tokens directly within the @injectable decorator. This allows a class to be registered under one or more specific tokens, simplifying resolution for multiple aliases. ```typescript interface Bar {} @injectable({token: "Bar"}) class Foo implements Bar {} @injectable({token: ["Bar", "Bar2"]}) class Baz implements Bar {} class MyRegistry {} const myBars = container.resolveAll("Bar"); // myBars type is Bar[], contains 2 instances const myBars2 = container.resolveAll("Bar2"); // myBars2 type is Bar[], contains 1 instance ``` -------------------------------- ### Optional Injection with @injectAll Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Demonstrates how to make @injectAll optional by passing `{ isOptional: true }`. This prevents exceptions when no registrations are found, returning an empty array instead. ```typescript import {injectable, injectAll} from "tsyringe"; @injectable() class Bar { constructor(@injectAll(Foo, { isOptional: true }) fooArray: Foo[]) { // ... } } ``` -------------------------------- ### Inject primitive values via named injection Source: https://www.npmjs.com/package/tsyringe?activeTab=code Explains how to inject primitive values (like strings) into constructors using the @inject decorator and container registration. ```typescript import {singleton, inject} from "tsyringe"; @singleton() class Foo { private str: string; constructor(@inject("SpecialString") value: string) { this.str = value; } } import "reflect-metadata"; import {container} from "tsyringe"; const str = "test"; container.register("SpecialString", {useValue: str}); const instance = container.resolve(Foo); ``` -------------------------------- ### Resolving All Instances with resolveAll() Source: https://www.npmjs.com/package/tsyringe?activeTab=code Retrieves all instances registered against a given token. This is useful when multiple implementations are registered for the same token, such as when using `useToken` or multiple `@injectable` decorators. ```typescript interface Bar {} @injectable() class Foo implements Bar {} @injectable() class Baz implements Bar {} @registry([ // registry is optional, all you need is to use the same token when registering {token: "Bar", useToken: Foo}, // can be any provider {token: "Bar", useToken: Baz} ]) class MyRegistry {} const myBars = container.resolveAll("Bar"); // myBars type is Bar[] ``` -------------------------------- ### Container Registration Providers Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Defines the structure for various tsyringe providers including Class, Value, and Factory providers, as well as the InjectionToken type. ```typescript type InjectionToken = | constructor | DelayedConstructor | string | symbol; // Class Provider { token: InjectionToken; useClass: constructor; } // Value Provider { token: InjectionToken; useValue: T } // Factory Provider { token: InjectionToken; useFactory: FactoryFunction; } import {instanceCachingFactory} from "tsyringe"; { token: "SingletonFoo"; useFactory: instanceCachingFactory(c => c.resolve(Foo)); } ``` -------------------------------- ### Define Token Provider Alias Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Configures a provider to act as a redirect or alias for an existing token. This maps one injection token to another. ```typescript { token: InjectionToken; useToken: InjectionToken; } ``` -------------------------------- ### Use injectable() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Marks a class as available for dependency injection, allowing the container to resolve its constructor dependencies. ```typescript import {injectable, container} from "tsyringe"; import "reflect-metadata"; @injectable() class Foo { constructor(private database: Database) {} } const instance = container.resolve(Foo); ``` -------------------------------- ### Configure TypeScript for Decorators Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Modify your `tsconfig.json` to enable experimental decorators and emit decorator metadata, which are necessary for TSyringe's functionality. ```json { "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } } ``` -------------------------------- ### Inject Primitive Values with Named Injection (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Demonstrates how to inject primitive values, such as strings, using named injection. This involves registering the value with a specific token and then injecting it using `@inject()`. ```typescript import { singleton, inject } from "tsyringe"; @singleton() class Foo { private str: string; constructor(@inject("SpecialString") value: string) { this.str = value; } } // some other file import "reflect-metadata"; import { container } from "tsyringe"; import { Foo } from "./foo"; const str = "test"; container.register("SpecialString", { useValue: str }); const instance = container.resolve(Foo); ``` -------------------------------- ### Resolving Single Instances with resolve() Source: https://www.npmjs.com/package/tsyringe?activeTab=code The typical method for obtaining an instance from the container. The `resolve()` method recursively fulfills dependencies to return a fully constructed object based on the provided token. ```typescript const myFoo = container.resolve(Foo); const myBar = container.resolve("Bar"); ``` -------------------------------- ### Use @inject() with Optional Parameter Source: https://www.npmjs.com/package/tsyringe?activeTab=code Explains how to make an injected dependency optional by passing `{ isOptional: true }` as the second argument to the `@inject()` decorator. This prevents errors if no registration is found, injecting `undefined` instead. ```typescript import {injectable, injectAll} from "tsyringe"; @injectable() class Foo { constructor(@inject("Database", { isOptional: true }) private database?: Database) {} } ``` -------------------------------- ### Dispose Container Instances (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Demonstrates how to dispose of all instances created by the container that implement the `Disposable` interface. This can be done synchronously or asynchronously. ```typescript container.dispose(); ``` ```typescript await container.dispose(); ``` -------------------------------- ### Resolve classes with interfaces Source: https://www.npmjs.com/package/tsyringe?activeTab=versions Explains how to use @inject decorators to resolve interfaces, which lack runtime type information. Requires registering the interface token to a concrete class implementation. ```TypeScript // Client.ts import {injectable, inject} from "tsyringe"; @injectable() export class Client { constructor(@inject("SuperService") private service: SuperService) {} } // main.ts container.register("SuperService", { useClass: TestService }); const client = container.resolve(Client); ``` -------------------------------- ### Factory Provider Registration Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Outlines the Factory Provider structure, which resolves a token using a factory function that has access to the dependency container. It includes `token` and `useFactory` properties. ```typescript { token: InjectionToken; useFactory: FactoryFunction; } ``` -------------------------------- ### Resolve dependencies with interfaces Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Explains how to resolve interface-based dependencies using the @inject decorator. Since interfaces lack runtime type information, they must be explicitly registered with the container. ```TypeScript // SuperService.ts export interface SuperService {} // TestService.ts import {SuperService} from "./SuperService"; export class TestService implements SuperService {} // Client.ts import {injectable, inject} from "tsyringe"; @injectable() export class Client { constructor(@inject("SuperService") private service: SuperService) {} } // main.ts import "reflect-metadata"; import {Client} from "./Client"; import {TestService} from "./TestService"; import {container} from "tsyringe"; container.register("SuperService", { useClass: TestService }); const client = container.resolve(Client); ``` -------------------------------- ### Resolve Class Without Interfaces (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Shows how to resolve a class instance from the container when the class does not implement any interfaces. This relies on runtime type information. ```typescript // Foo.ts export class Foo {} // Bar.ts import { Foo } from "./Foo"; import { injectable } from "tsyringe"; @injectable() export class Bar { constructor(public myFoo: Foo) {} } // main.ts import "reflect-metadata"; import { container } from "tsyringe"; import { Bar } from "./Bar"; const myBar = container.resolve(Bar); // myBar.myFoo will be an instance of Foo ``` -------------------------------- ### Clearing Instances with Tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Demonstrates the `clearInstances` method for removing all previously created and registered instances from the container. This method preserves registrations but discards singleton and instance scopes, making it useful for testing scenarios where a clean state is required before each test. ```typescript class Foo {} @singleton() class Bar {} const myFoo = new Foo(); container.registerInstance("Test", myFoo); const myBar = container.resolve(Bar); container.clearInstances(); container.resolve("Test"); // throws error const myBar2 = container.resolve(Bar); // myBar !== myBar2 const myBar3 = container.resolve(Bar); // myBar2 === myBar3 ``` ```typescript @singleton() class Foo {} beforeEach(() => { container.clearInstances(); }); test("something", () => { container.resolve(Foo); // will be a new singleton instance in every test }); ``` -------------------------------- ### Create hierarchical child containers Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Creates child containers that inherit registrations from a parent. Child containers allow for isolated registrations while falling back to the parent for missing dependencies. ```typescript const childContainer1 = container.createChildContainer(); const childContainer2 = container.createChildContainer(); const grandChildContainer = childContainer1.createChildContainer(); ``` -------------------------------- ### Resolve Class Instance with Interfaces (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Illustrates how to resolve a class instance when interfaces are used. Since interfaces lack runtime type information, they need to be explicitly mapped using `@inject(...)` and `container.register()`. ```typescript // SuperService.ts export interface SuperService { // ... } ``` ```typescript // TestService.ts import { SuperService } from "./SuperService"; export class TestService implements SuperService { //... } ``` ```typescript // Client.ts import { injectable, inject } from "tsyringe"; @injectable() export class Client { constructor(@inject("SuperService") private service: SuperService) {} } ``` ```typescript // main.ts import "reflect-metadata"; import { Client } from "./Client"; import { TestService } from "./TestService"; import { container } from "tsyringe"; container.register("SuperService", { useClass: TestService, }); const client = container.resolve(Client); // client's dependencies will have been resolved ``` -------------------------------- ### Handling Circular Dependencies with `delay` in tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=versions Resolve circular dependencies between services by using the `delay` helper function. `delay` wraps constructors, creating a proxy that defers actual instantiation until first use, thus breaking the cycle. ```typescript @injectable() export class Foo { constructor(@inject(delay(() => Bar)) public bar: Bar) {} } @injectable() export class Bar { constructor(@inject(delay(() => Foo)) public foo: Foo) {} } // construction of foo is possible const foo = container.resolve(Foo); // property bar will hold a proxy that looks and acts as a real Bar instance. foo.bar instanceof Bar; // true ``` -------------------------------- ### Value Provider Registration Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Defines the structure of a Value Provider, used for resolving a token to a specific pre-instantiated value. It consists of `token` and `useValue` properties. ```typescript { token: InjectionToken; useValue: T } ``` -------------------------------- ### Use @singleton() Decorator Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Apply the `@singleton()` decorator to a class to register it as a singleton within the global TSyringe container, ensuring only one instance is ever created. ```typescript import {singleton} from "tsyringe"; @singleton() class Foo { constructor() {} } // some other file import "reflect-metadata"; import {container} from "tsyringe"; import {Foo} from "./foo"; const instance = container.resolve(Foo); ``` -------------------------------- ### Registering After Resolution Callback with Tsyringe Source: https://www.npmjs.com/package/tsyringe?activeTab=dependencies Illustrates the use of `afterResolution` to execute a callback after an object has been successfully resolved. This is ideal for post-resolution tasks such as initialization or cleanup. The callback receives the token, the resolved result, and the resolution type. ```typescript class Bar { public init(): void { // ... } } container.afterResolution( Bar, // Callback signature is (token: InjectionToken, result: T | T[], resolutionType: ResolutionType) (_t, result) => { result.init(); }, {frequency: "Once"} ); ``` -------------------------------- ### Resolve Class Instance without Interfaces (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Shows how to resolve a class instance when no interfaces are involved. Tsyringe can resolve classes directly due to runtime type information. ```typescript // Foo.ts export class Foo {} ``` ```typescript // Bar.ts import { Foo } from "./Foo"; import { injectable } from "tsyringe"; @injectable() export class Bar { constructor(public myFoo: Foo) {} } ``` ```typescript // main.ts import "reflect-metadata"; import { container } from "tsyringe"; import { Bar } from "./Bar"; const myBar = container.resolve(Bar); // myBar.myFoo => An instance of Foo ``` -------------------------------- ### Check Registration Status Source: https://www.npmjs.com/package/tsyringe?activeTab=readme Uses isRegistered() to verify if a token exists in the container. Supports recursive checking in parent containers for child containers. ```typescript const isRegistered = container.isRegistered("Bar"); // Recursive check in parent container childContainer.isRegistered(Bar, true); ``` -------------------------------- ### Use @inject() Decorator for Named Injection Source: https://www.npmjs.com/package/tsyringe?activeTab=code Demonstrates the `@inject()` parameter decorator, used for injecting dependencies identified by an injection token (like a string or symbol), especially useful for non-class types or named registrations. ```typescript import {injectable, inject} from "tsyringe"; interface Database { // ... } @injectable() class Foo { constructor(@inject("Database") private database?: Database) {} } ``` -------------------------------- ### Container Registration Providers Source: https://www.npmjs.com/package/tsyringe?activeTab=code Defines the structure for various container providers including Class, Value, and Factory providers used to register tokens in the DI container. ```typescript type InjectionToken = | constructor | DelayedConstructor | string | symbol; // Class Provider { token: InjectionToken; useClass: constructor; } // Value Provider { token: InjectionToken; useValue: T } // Factory Provider { token: InjectionToken; useFactory: FactoryFunction; } import {instanceCachingFactory} from "tsyringe"; { token: "SingletonFoo"; useFactory: instanceCachingFactory(c => c.resolve(Foo)); } ``` -------------------------------- ### Resolve Class With Interfaces (TypeScript) Source: https://www.npmjs.com/package/tsyringe?activeTab=dependents Illustrates how to resolve a class instance when it implements an interface. Since interfaces lack runtime type information, the `@inject` decorator is used to map the interface name to its implementation. ```typescript // SuperService.ts export interface SuperService { // ... } // TestService.ts import { SuperService } from "./SuperService"; export class TestService implements SuperService { //... } // Client.ts import { injectable, inject } from "tsyringe"; @injectable() export class Client { constructor(@inject("SuperService") private service: SuperService) {} } // main.ts import "reflect-metadata"; import { Client } from "./Client"; import { TestService } from "./TestService"; import { container } from "tsyringe"; container.register("SuperService", { useClass: TestService }); const client = container.resolve(Client); // client's dependencies will have been resolved ```