### Install Dioma using npm or yarn Source: https://github.com/zheksoon/dioma/blob/main/README.md Instructions for installing the Dioma dependency injection library using package managers like npm and yarn. This is the first step to integrate Dioma into your project. ```sh npm install --save dioma ``` ```sh yarn add dioma ``` -------------------------------- ### Dioma: Transient Scope Example Source: https://github.com/zheksoon/dioma/blob/main/README.md Provides a specific example of using the Transient scope in Dioma, where a new instance of a dependency is created on every injection. This snippet highlights the `Scopes.Transient()` configuration. ```typescript import { inject, Scopes } from "dioma"; class Engine { start() { console.log("Engine started"); } static scope = Scopes.Singleton(); } class Vehicle { constructor(private engine = inject(Engine)) {} drive() { this.engine.start(); console.log("Vehicle driving"); } static scope = Scopes.Transient(); } // New vehicle every time const vehicle = inject(Vehicle); vehicle.drive(); ``` -------------------------------- ### Dioma: Container Scope Example Source: https://github.com/zheksoon/dioma/blob/main/README.md Illustrates how to use Dioma's Container scope for managing dependencies within a specific container instance. It shows creating a custom container, registering classes, and injecting dependencies using `container.inject`. ```typescript import { Container, Scopes } from "dioma"; const container = new Container(); class Garage { open() { console.log("garage opened"); } // Single instance of the class for the container static scope = Scopes.Container(); } // Register Garage on the container container.register({ class: Garage }); class Car { // Use inject method of the container for Garage constructor(private garage = container.inject(Garage)) {} park() { this.garage.open(); console.log("car parked"); } // New instance on every injection static scope = Scopes.Transient(); } const car = container.inject(Car); car.park(); ``` -------------------------------- ### Dioma Async Injection with Classes Source: https://github.com/zheksoon/dioma/blob/main/README.md Demonstrates how to resolve circular dependencies using `injectAsync`. This example shows classes A and B depending on each other asynchronously, resolving the dependency chain via promises. ```typescript import { inject, injectAsync, Scopes } from "dioma"; class A { constructor(private instanceB = inject(B)) {} doWork() { console.log("doing work A"); this.instanceB.help(); } static scope = Scopes.Singleton(); } class B { private declare instanceA: A; // injectAsync returns a promise of the A instance constructor(private promiseA = injectAsync(A)) { this.promiseA.then((instance) => { this.instanceA = instance; }); } help() { console.log("helping with work"); } doAnotherWork() { console.log("doing work B"); this.instanceA.doWork(); } static scope = Scopes.Singleton(); } const a = await injectAsync(A); const b = await injectAsync(B); // Wait until all promises are resolved await globalContainer.waitAsync(); a.doWork(); b.doAnotherWork(); ``` -------------------------------- ### Demonstrate Resolution Scope in Dioma Source: https://github.com/zheksoon/dioma/blob/main/README.md Illustrates the 'Resolution' scope in Dioma, where a new instance is created per resolution but remains the same throughout that resolution. This is useful for managing dependencies within a single request or operation lifecycle. ```typescript import { inject, Scopes } from "dioma"; class Query { static scope = Scopes.Resolution(); } class RequestHandler { constructor(public query = inject(Query)) {} static scope = Scopes.Resolution(); } class RequestUser { constructor( public request = inject(RequestHandler), public query = inject(Query) ) {} static scope = Scopes.Transient(); } const requestUser = inject(RequestUser); // The same instance of Query is used for each of them requestUser.query === requestUser.request.query; ``` -------------------------------- ### Dioma: Basic Singleton and Transient Scope Usage Source: https://github.com/zheksoon/dioma/blob/main/README.md Demonstrates the fundamental usage of Dioma for dependency injection, showcasing how to define classes with static scope properties and inject them using the `inject` function. It illustrates both Singleton and Transient scopes. ```typescript import { inject, Scopes } from "dioma"; class Garage { open() { console.log("garage opened"); } // Single instance of the class for the entire application static scope = Scopes.Singleton(); } class Car { // injects instance of Garage constructor(private garage = inject(Garage)) {} park() { this.garage.open(); console.log("car parked"); } // New instance of the class on every injection static scope = Scopes.Transient(); } // Creates a new Car and injects Garage const car = inject(Car); car.park(); ``` -------------------------------- ### Dioma Injection Hooks Source: https://github.com/zheksoon/dioma/blob/main/README.md Shows how to define `beforeInject` and `beforeCreate` hooks when registering a class. These hooks are executed before the instance is created or injected, allowing for custom logic or side effects. ```typescript container.register({ class: MyClass, beforeInject: (container, descriptor, args) => { console.log("Before inject"); }, beforeCreate: (container, descriptor, args) => { console.log("Before create"); }, }); ``` -------------------------------- ### Value Token Injection with Dioma Source: https://github.com/zheksoon/dioma/blob/main/README.md Demonstrates how to use value tokens in Dioma to inject constant values into your application. This is useful for providing configuration settings or other literal data. ```typescript import { Token } from "dioma"; const token = new Token("Value token"); container.register({ token, value: "Value" }); const value = container.inject(token); console.log(value); // Value ``` -------------------------------- ### Dioma Factory Tokens Source: https://github.com/zheksoon/dioma/blob/main/README.md Demonstrates how to use factory tokens to inject dynamically created values. The factory function receives the container and can return any value, supporting additional arguments for custom logic. ```typescript import { Token } from "dioma"; const token = new Token("Factory token"); container.register({ token, factory: (container) => "Value" }); const value = container.inject(token); console.log(value); // Value ``` ```typescript const token = new Token("Factory token"); container.register({ token, factory: (container, a: string, b): string => a + b, }); const value = container.inject(token, "Hello, ", "world!"); console.log(value); // Hello, world! ``` -------------------------------- ### Dioma Async Injection with Tokens Source: https://github.com/zheksoon/dioma/blob/main/README.md Illustrates using `injectAsync` with tokens to handle asynchronous dependencies. This pattern is useful for resolving dependencies where the target instance might be created asynchronously. ```typescript import { Token, Scopes, injectAsync } from "dioma"; // Assuming class A and its registration are defined elsewhere // class A { ... } // container.register({ token: new Token("A"), class: A, scope: Scopes.Singleton() }); const token = new Token("A"); class B { private declare instanceA: A; // token is used for async injection constructor(private promiseA = injectAsync(token)) { this.promiseA.then((instance) => { this.instanceA = instance; }); } // ... other methods for class B } ``` -------------------------------- ### Register and Manage Classes with Dioma Containers Source: https://github.com/zheksoon/dioma/blob/main/README.md Demonstrates class registration within Dioma containers, including creating child containers, registering classes to specific containers, overriding scopes, and unregistering classes. Registered classes maintain their instance across child containers if registered in a parent. ```typescript const container = new Container(); const child = container.childContainer(); class FooBar { static scope = Scopes.Container(); } // Register the Foo class in the parent container container.register({ class: FooBar }); // Returns and cache the instance on parent container const foo = container.inject(FooBar); // Returns the FooBar instance from the parent container const bar = child.inject(FooBar); foo === bar; // true // You can override the scope of the registered class: container.register({ class: FooBar, scope: Scopes.Transient() }); // To unregister a class, use the `unregister` method: container.unregister(FooBar); ``` -------------------------------- ### Class Token Injection with Multiple Implementations Source: https://github.com/zheksoon/dioma/blob/main/README.md Explains how to use class tokens with Dioma to inject abstract classes or interfaces that have multiple concrete implementations. This allows for flexible dependency management and swapping implementations. ```typescript import { Token, Scopes, globalContainer } from "dioma"; const wild = globalContainer.childContainer("Wild"); const zoo = wild.childContainer("Zoo"); interface IAnimal { speak(): void; } class Dog implements IAnimal { speak() { console.log("Woof"); } static scope = Scopes.Container(); } class Cat implements IAnimal { speak() { console.log("Meow"); } static scope = Scopes.Container(); } const animalToken = new Token("Animal"); // Register Dog class with the token wild.register({ token: animalToken, class: Dog }); // Register Cat class with the token zoo.register({ token: animalToken, class: Cat }); // Returns Dog instance const wildAnimal = wild.inject(animalToken); // Returns Cat instance const zooAnimal = zoo.inject(animalToken); // The class token registration can also override the scope of the class: wild.register({ token: animalToken, class: Dog, scope: Scopes.Transient() }); ``` -------------------------------- ### Dioma Async Resolution Behavior Source: https://github.com/zheksoon/dioma/blob/main/README.md Explains the behavior and considerations for asynchronous injection, particularly regarding circular dependencies with transient scopes and the necessity of `container.waitAsync()` or waiting for the next tick to ensure all promises are resolved. ```APIDOC Async Injection Behavior: - Circular dependencies with transient dependencies can lead to undefined behavior or errors like `Circular dependency detected in async resolution`. It is recommended to avoid such configurations. - After using `await injectAsync(...)`, it is crucial to ensure all asynchronous operations are completed. This can be achieved by calling `container.waitAsync()` or waiting for the next event loop tick. - Even when using `await injectAsync(...)`, explicit waiting mechanisms like `container.waitAsync()` are necessary to guarantee that all pending promises for instance creation are resolved before proceeding. - For dependencies expected to resolve asynchronously, `injectAsync` is the preferred method. However, `inject` can also be used for async resolution provided the promise is explicitly awaited as demonstrated in the examples. ``` -------------------------------- ### TypeScript Type Safety and Injection Source: https://github.com/zheksoon/dioma/blob/main/README.md Demonstrates Dioma's type safety features, including defining injectable classes with scopes, injecting dependencies using the `inject` function, and highlighting potential type errors when scopes are not specified. ```typescript import { inject, Scopes, Injectable } from "dioma"; // Injectable interface makes sure the static scope is defined class Database implements Injectable { constructor(private url: string) {} connect() { console.log(`Connected to ${this.url}`); } static scope = Scopes.Singleton(); } // Error, scope is not specified class Repository implements Injectable { constructor(private db = inject(Database)) {} } inject(Repository); // Also type error, scope is not specified ``` -------------------------------- ### Dioma Child Containers Source: https://github.com/zheksoon/dioma/blob/main/README.md Illustrates the creation and usage of child containers for scope isolation. Dioma searches for instances top-down in the container hierarchy, creating them in the current or registered container if not found. ```typescript import { Container, Scopes } from "dioma"; const container = new Container(null, "Parent"); const child = container.childContainer("Child"); class ParentClass { static scope = Scopes.Container(); } class ChildClass { static scope = Scopes.Container(); } container.register({ class: ParentClass }); child.register({ class: ChildClass }); // Returns ParentClass instance from the parent container const parentInstance = child.inject(ParentClass); // Returns ChildClass instance from the child container const childInstance = child.inject(ChildClass); ``` -------------------------------- ### Inject Arguments into Constructor with Dioma Source: https://github.com/zheksoon/dioma/blob/main/README.md Shows how to pass arguments directly to a class constructor during injection using Dioma. This feature is supported for Transient and Resolution scopes, with arguments being passed only once for Resolution scope instances. ```typescript import { inject, Scopes } from "dioma"; class Owner { static scope = Scopes.Singleton(); petSomebody(pet: Pet) { console.log(`${pet.name} petted`); } } class Pet { constructor(public name: string, public owner = inject(Owner)) {} pet() { this.owner.petSomebody(this); } static scope = Scopes.Transient(); } const pet = inject(Pet, "Fluffy"); pet.pet(); // Fluffy petted ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.