Skip to main content
Home

@eser/di@0.7.24
Built and signed on GitHub Actions

This package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers
This package works with Cloudflare Workers
This package works with Node.js
This package works with Deno
This package works with Bun
This package works with Browsers
JSR Score
64%
Published
2 months ago (0.7.24)

⚙️ @eser/di

@eser/di is a crucial component of eserstack that provides simple and efficient dependency injection solutions.

🚀 Getting Started with Dependency Injection (DI)

Dependency injection is a software design pattern that enables the removal of hard-coded dependencies from the code, making it possible to change them whenever needed.

By promoting loose coupling, it enhances the testability and maintainability of the overall codebase structure.

Dependency Injection Container (DIC)

A dependency injection container is a software component responsible for the instantiation and distribution of services or objects in your code. It simplifies the management of dependencies by serving as a central registry for all services.

🤔 What @eser/di offers?

@eser/di helps you handle these dependencies by providing a structured, scalable and proper way to manage dependencies in your application. While its dependency injection container is focused on simplicity and efficiency, it also provides a set of decorators to make managing your application's services and dependencies even easier.

🛠 Usage

Here you'll find a list of features provided by @eser/di along with brief descriptions and usage examples.

Registering services

Start by creating a registry and registering your services using the set, setLazy, setScoped and setTransient methods.

import { registry } from "@eser/di";

// Register the mailService as a singleton service
registry.set("mailService", new MailService());

// Register the notifyService as a singleton service
registry.set("notifyService", new PushNotificationService());

// Register the dbConnection as a transient service,
// which is created anew each time it is called
registry.setTransient("dbConnection", () => new DatabaseConnection());

// Register the userList as a lazy-loaded service,
// which is created when first called
registry.setLazy(
  "userList",
  (container) => container.get("dbConnection").query("SELECT * FROM users"),
);

Alternatively, you can chain the registration methods:

import { registry } from "@eser/di";

registry
  .set("mailService", new MailService())
  .set("notifyService", new PushNotificationService())
  .setTransient("dbConnection", () => new DatabaseConnection())
  .setLazy(
    "userList",
    (container) => container.get("dbConnection").query("SELECT * FROM users"),
  );

Retrieving services

Once you have the services container, you may retrieve your services using the get, getMany, invoke methods. Even better, you can use the di template literal tag to retrieve services.

import { di } from "@eser/di";

// Retrieve registered services
const dns = di`mailService`;
const mns = di`notifyService`;
const db = di`dbConnection`;
const users = di`userList`;

Alternatively, retrieve multiple services at once:

import { services } from "@eser/di";

const [dns, mns, db, users] = di.getMany(
  "mailService",
  "notifyService",
  "dbConnection",
  "userList",
);

You can directly call your functions using the registered services as parameters:

import { registry } from "@eser/di";

di.set("serviceA", () => console.log("Service A"));
di.set("serviceB", () => console.log("Service B"));

function myFunction(serviceA, serviceB) {
  serviceA();
  serviceB();
}

di.invoke(myFunction); // This will log "Service A" and then "Service B"

Template Strings

You can use the di template literal tag to easily retrieve services using template strings. This provides a more readable and concise way to access your dependencies.

import { registry } from "@eser/di";

di.set("serviceA", () => console.log("Service A"));
di.set("serviceB", () => console.log("Service B"));

di`first: ${"serviceA"} second: ${"serviceB"}`; // This will log "first: Service A second: Service B"

Decorators

import { di, injectable } from "@eser/di";

@injectable()
class PrinterClass {
  print() {
    console.log("testing");
  }
}

const test = di`PrinterClass`;
test.print(); // outputs "testing"

📕 API Reference

The following is a list of all available methods and their descriptions.

Registry

set(key: string | symbol | object, value: any): Registry
Registers a singleton service with the specified key.

setLazy(key: string | symbol | object, factory: () => any): Registry
Registers a lazy-loaded service with the specified key. The value is created when first called.

setScoped(key: string | symbol | object, factory: () => any): Registry
Registers a scoped service with the specified key. The value is created once per scope.

setTransient(key: string | symbol | object, factory: () => any): Registry
Registers a transient service with the specified key. The value is created anew each time it is called.

build(): Container
Builds a dependency injection container with the registered services.

Container

get(key: string | symbol | object, defaultValue?: any): any
Returns the corresponding service to the specified key.

getMany(...keys: (string | symbol | object)[]): any[]
Returns the corresponding services to the specified keys in an array.

createScope(): Container
Initiates a new scope. Each new scope inherits all services from the root scope except those marked as 'scoped'. Scoped services are instantiated just once per scope. When a scope is closed (or disposed), all its scoped services lose their references as if they were never instantiated.


🔗 For further details such as requirements, licensing and support guide, please visit the main eserstack repository.

Built and signed on
GitHub Actions

New Ticket: Report package

Please provide a reason for reporting this package. We will review your report and take appropriate action.

Please review the JSR usage policy before submitting a report.

Add Package

deno add jsr:@eser/di

Import symbol

import * as di from "@eser/di";
or

Import directly with a jsr specifier

import * as di from "jsr:@eser/di";

Add Package

pnpm i jsr:@eser/di
or (using pnpm 10.8 or older)
pnpm dlx jsr add @eser/di

Import symbol

import * as di from "@eser/di";

Add Package

yarn add jsr:@eser/di
or (using Yarn 4.8 or older)
yarn dlx jsr add @eser/di

Import symbol

import * as di from "@eser/di";

Add Package

vlt install jsr:@eser/di

Import symbol

import * as di from "@eser/di";

Add Package

npx jsr add @eser/di

Import symbol

import * as di from "@eser/di";

Add Package

bunx jsr add @eser/di

Import symbol

import * as di from "@eser/di";