Skip to content

@Inject ​

@Inject(token) is a constructor-parameter decorator that tells inject which token to resolve for that parameter. It is the primary way to declare a dependency.

ts
import { inject, Inject, Injectable } from '@remotex-labs/xinject';

@Injectable()
class Logger {}

@Injectable()
class UserService {
    constructor(@Inject(Logger) private logger: Logger) {}
}

inject(UserService); // logger is resolved and passed automatically

How a token resolves ​

A token can be a class, an abstract class, an InjectionToken, or a plain string / symbol. For each @Inject(token) parameter, inject looks the token up in the class's providers registry:

  • Found - it is resolved through its binding (useValue, useClass, useFactory).
  • Not found, and the token is a class - the class self-injects, so a plain class dependency needs no provider entry.
  • Not found, and the token is anything else (InjectionToken, abstract class, string, symbol) - inject throws No provider for <token>.
ts
const SQL = new InjectionToken<string>('SQL');

@Injectable({ providers: [{ provide: SQL, useValue: 'SELECT * FROM users' }] })
class Database {
    constructor(
        @Inject(Logger) public logger: Logger, // class token -> self-injects
        @Inject(SQL)    public sql: string,     // InjectionToken -> resolved from providers
    ) {}
}

Resolution is by token, not by position, so the order of parameters and of providers entries does not matter.

Overriding with an explicit argument ​

An argument passed to inject wins over the @Inject token at the same position - useful for tests and one-off overrides:

ts
const stub = new Logger();

inject(UserService, stub).logger === stub; // true

Undecorated parameters ​

A parameter without @Inject is not resolved from the container. It is filled only by an explicit argument to inject, and is otherwise undefined:

ts
@Injectable()
class Api {
    constructor(public url: string) {} // no @Inject
}

inject(Api, 'https://example.com').url; // 'https://example.com'
inject(Api).url;                         // undefined

For a value dependency you want the container to own, bind it to an InjectionToken and @Inject it instead.

Released under the Mozilla Public License 2.0