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