Skip to main content
Module

x/alosaur/src/injection/README.md

Alosaur - Deno web framework with many decorators
Very Popular
Go to Latest
File

TSyringe for alosaur

A lightweight dependency injection container for TypeScript/JavaScript for constructor injection. TSyringe

API

Injectable()

Class decorator factory that allows the class’ dependencies to be injected at runtime.

Usage

import {Injectable} from "https://deno.land/x/alosaur/mod.ts";

@Injectable()
class Foo {
  constructor(private database: Database) {}
}

// some other file
import {container} from "https://deno.land/x/alosaur/mod.ts";
import {Foo} from "./foo";

const instance = container.resolve(Foo);

Singleton()

Class decorator factory that registers the class as a singleton within the global container.

Usage

import {Singleton} from "https://deno.land/x/alosaur/mod.ts";

@Singleton()
class Foo {
  constructor() {}
}

// some other file
import {container} from "https://deno.land/x/alosaur/mod.ts";
import {Foo} from "./foo";

const instance = container.resolve(Foo);

AutoInjectable()

Class decorator factory that replaces the decorated class’ constructor with a parameterless constructor that has dependencies auto-resolved.

Note Resolution is performed using the global container

Usage

import {AutoInjectable} from "https://deno.land/x/alosaur/mod.ts";

@AutoInjectable()
class Foo {
  constructor(private database?: Database) {}
}

// some other file
import {Foo} from "./foo";

const instance = new Foo();

Notice how in order to allow the use of the empty constructor new Foo(), we need to make the parameters optional, e.g. database?: Database

Inject()

Parameter decorator factory that allows for interface and other non-class information to be stored in the constructor’s metadata

Usage

import {Injectable, Inject} from "https://deno.land/x/alosaur/mod.ts";

interface Database {
  // ...
}

@Injectable()
class Foo {
  constructor(@Inject("Database") private database?: Database) {}
}

Full examples

Example without interfaces

Since classes have type information at runtime, we can resolve them without any extra information.

// Foo.ts
export class Foo {}
// Bar.ts
import {Foo} from "./Foo";
import {Injectable} from "https://deno.land/x/alosaur/mod.ts";

@Injectable()
export class Bar {
  constructor(public myFoo: Foo) {}
}
// main.ts
import {container} from "https://deno.land/x/alosaur/mod.ts";
import {Bar} from "./Bar";

const myBar = container.resolve(Bar);
// myBar.myFoo => An instance of Foo

Example with interfaces

Interfaces don’t have type information at runtime, so we need to decorate them with @Inject(...) so the container knows how to resolve them.

// SuperService.ts
export interface SuperService {
  // ...
}
// TestService.ts
import {SuperService} from "./SuperService";
export class TestService implements SuperService {
  //...
}
// Client.ts
import {Injectable, Inject} from "https://deno.land/x/alosaur/mod.ts";

@Injectable()
export class Client {
  constructor(@Inject("SuperService") private service: SuperService) {}
}
// main.ts
import {Client} from "./Client";
import {TestService} from "./TestService";
import {container} from "https://deno.land/x/alosaur/mod.ts";

container.register("SuperService", {
  useClass: TestService
});

const client = container.resolve(Client);
// client's dependencies will have been resolved