Dependency Injection

Aurelia's dependency injection (DI) system manages your application's services and their dependencies automatically, promoting clean architecture and testable code.

Creating Services

Services are regular classes that encapsulate state and call out to other dependencies. Rather than assigning collaborators manually, grab them from the container via resolve():

import { resolve } from '@aurelia/kernel';
import { IHttpClient } from '@aurelia/fetch-client';

export class UserService {
  private readonly http = resolve(IHttpClient);
  private readonly cache: User[] = [];

  async getUsers(): Promise<User[]> {
    const response = await this.http.fetch('/api/users');
    const payload = await response.json();
    this.cache.splice(0, this.cache.length, ...payload);
    return this.cache;
  }

  async createUser(userData: CreateUserRequest): Promise<User> {
    const response = await this.http.fetch('/api/users', {
      method: 'POST',
      body: JSON.stringify(userData),
      headers: { 'Content-Type': 'application/json' },
    });
    const user = await response.json();
    this.cache.push(user);
    return user;
  }
}

Service Registration

Register services using the interface pattern so components depend on tokens, not classes:

When this module loads the container wires IUserService to a singleton UserService instance. Swapping implementations (e.g., a mock service in tests) only requires a different registration.

Using Services in Components

Use the resolve() function to inject services into components:

Why resolve()?

  • Clean, modern syntax

  • No decorators needed

  • Better TypeScript inference

  • Easier to test

Service Dependencies

Services can depend on other services using resolve():

You can resolve multiple dependencies - Aurelia handles the wiring automatically.

Service Lifetimes

Control how services are instantiated:

Configuration Services

Create configuration objects for your services:

Resolver toolbox

The DI container ships a set of resolver helpers in @aurelia/kernel. Resolvers change how a dependency is located at runtime—perfect for optional services, per-scope instances, or discovering every implementation of an interface. Every resolver works both as a decorator (@all(IMetricSink)) and inside resolve(...).

Resolver
Example
What it does

all(key)

resolve(all(IMetricSink))

Returns all registrations for a key (useful for plugin pipelines).

last(key)

resolve(last(ISink))

Grabs the most recently registered instance.

lazy(key)

resolve(lazy(IHttpClient))

Injects a function that resolves the dependency on demand.

optional(key) / own(key)

resolve(optional(IMaybeService))

Returns undefined (or the child container value) when nothing is registered.

factory(key)

resolve(factory(MyModelClass))

Gives you a function that constructs the service manually (passing constructor args if needed).

newInstanceForScope(key)

resolve(newInstanceForScope(IValidationController))

Creates and registers a brand-new instance in the current component scope, making it available to descendants via resolve(IValidationController).

newInstanceOf(Type)

resolve(newInstanceOf(Logger))

Constructs a fresh instance of a concrete class or interface implementation without polluting the container.

resource(key) / optionalResource(key) / allResources(key)

resolve(optionalResource(MyElement))

Resolves using resource semantics (look in the current component first, then root) which is handy for templating resources.

ignore

@ignore private unused?: Foo

Tells the container to skip a constructor parameter completely.

Creating custom resolvers

If none of the built-ins fit, use createResolver to craft your own semantics. The helper wires up decorator + runtime support automatically:

Because resolvers are plain DI registrations, you can package them inside libraries or register them globally via Aurelia.register(...), keeping consumption ergonomic in templates and services alike.

Testing with DI

DI makes testing straightforward by allowing easy mocking:

What's Next

Last updated

Was this helpful?