CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-theia--core

Core framework for building cloud and desktop IDE applications using modern web technologies with TypeScript and dependency injection.

Pending
Overview
Eval results
Files

dependency-injection.mddocs/

Dependency Injection System

Theia Core provides comprehensive dependency injection infrastructure built on InversifyJS, featuring Symbol-based service tokens, contribution patterns, and container management for building extensible applications.

Capabilities

Injectable Decorator

Marks a class as injectable for dependency injection container binding.

/**
 * Marks a class as available for injection
 * @param target - The class to mark as injectable
 * @returns The injectable class
 */
function injectable<T>(target: interfaces.Newable<T>): interfaces.Newable<T>;

Usage Example:

import { injectable } from "@theia/core";

@injectable()
export class MyService {
    doSomething(): void {
        console.log("Service method called");
    }
}

Inject Decorator

Injects dependencies into constructor parameters or properties.

/**
 * Injects a service into a constructor parameter
 * @param serviceIdentifier - Symbol or string identifying the service
 * @returns Parameter decorator
 */
function inject(serviceIdentifier: interfaces.ServiceIdentifier): ParameterDecorator;

Usage Examples:

import { injectable, inject } from "@theia/core";
import { ILogger } from "@theia/core";

@injectable()
export class MyComponent {
    constructor(
        @inject(ILogger) private readonly logger: ILogger
    ) {}
    
    performAction(): void {
        this.logger.info("Action performed");
    }
}

Contribution Provider

Collects and provides access to all bound contributions of a specific type.

/**
 * Provider for collecting contributions of a specific type
 */
interface ContributionProvider<T> {
    /**
     * Get all contributions of type T
     * @returns Array of all bound contributions
     */
    getContributions(): T[];
    
    /**
     * Get all contributions of type T that satisfy the filter
     * @param filter - Optional filter function
     * @returns Filtered array of contributions
     */
    getContributions(filter?: (contrib: T) => boolean): T[];
}

/**
 * Symbol for binding ContributionProvider
 */
const ContributionProvider: symbol;

Usage Example:

import { injectable, inject } from "@theia/core";
import { ContributionProvider, CommandContribution } from "@theia/core";

@injectable()
export class CommandManager {
    constructor(
        @inject(ContributionProvider) @named(CommandContribution)
        private readonly contributions: ContributionProvider<CommandContribution>
    ) {}
    
    initializeCommands(): void {
        for (const contribution of this.contributions.getContributions()) {
            contribution.registerCommands(/* registry */);
        }
    }
}

Binding Functions

Utility functions for binding contributions and providers to the container.

/**
 * Binds a contribution provider to the container
 * @param bind - Container bind function
 * @param id - Service identifier for the contribution type
 */
function bindContributionProvider(
    bind: interfaces.Bind, 
    id: interfaces.ServiceIdentifier
): void;

/**
 * Binds a single contribution to the container
 * @param bind - Container bind function
 * @param id - Service identifier for the contribution type
 * @param contribution - The contribution class to bind
 */
function bindContribution<T>(
    bind: interfaces.Bind,
    id: interfaces.ServiceIdentifier<T>,
    contribution: interfaces.Newable<T>
): void;

Usage Example:

import { ContainerModule } from "inversify";
import { bindContributionProvider, CommandContribution } from "@theia/core";

export default new ContainerModule(bind => {
    // Bind the contribution provider
    bindContributionProvider(bind, CommandContribution);
    
    // Bind individual contributions
    bind(CommandContribution).to(MyCommandContribution).inSingletonScope();
    bind(CommandContribution).to(AnotherCommandContribution).inSingletonScope();
});

Named Binding

Decorator for named service bindings when multiple implementations exist.

/**
 * Named binding decorator for distinguishing between multiple implementations
 * @param name - The name to identify this binding
 * @returns Parameter decorator
 */
function named(name: string | number | symbol): ParameterDecorator;

Usage Example:

import { injectable, inject, named } from "@theia/core";

interface StorageService {
    get(key: string): string | undefined;
    set(key: string, value: string): void;
}

@injectable()
export class ConfigurationManager {
    constructor(
        @inject('StorageService') @named('user')
        private readonly userStorage: StorageService,
        
        @inject('StorageService') @named('workspace') 
        private readonly workspaceStorage: StorageService
    ) {}
}

Container Management

Utilities for working with InversifyJS containers in Theia applications.

/**
 * Application container type
 */
type ApplicationContainer = interfaces.Container;

/**
 * Bindable type for flexible binding
 */
type Bindable = interfaces.Bind | interfaces.Container;

Usage Example:

import { Container, ContainerModule } from "inversify";
import { bindContributionProvider } from "@theia/core";

// Create application container
const container = new Container();

// Load extension modules
const extensionModule = new ContainerModule(bind => {
    bindContributionProvider(bind, CommandContribution);
    bind(MyService).toSelf().inSingletonScope();
});

container.load(extensionModule);

// Get services
const myService = container.get(MyService);

Optional Injection

Handle optional dependencies that may not be bound.

/**
 * Optional injection decorator
 * @param serviceIdentifier - Service identifier
 * @returns Parameter decorator that allows undefined injection
 */
function optional(): ParameterDecorator;

Usage Example:

import { injectable, inject, optional } from "@theia/core";

@injectable()
export class OptionalServiceConsumer {
    constructor(
        @inject('RequiredService') private readonly required: RequiredService,
        @inject('OptionalService') @optional() 
        private readonly optional?: OptionalService
    ) {}
    
    performAction(): void {
        // Always available
        this.required.doSomething();
        
        // Check if optional service is available
        if (this.optional) {
            this.optional.doOptionalThing();
        }
    }
}

Service Binding Patterns

Singleton Scope

Most Theia services should be bound in singleton scope:

bind(MyService).toSelf().inSingletonScope();

Contribution Pattern

Extensions contribute implementations through the contribution pattern:

// 1. Define contribution interface
interface MyContribution {
    configure(): void;
}

// 2. Bind contribution provider
bindContributionProvider(bind, MyContribution);

// 3. Extensions bind their implementations
bind(MyContribution).to(MyImplementation).inSingletonScope();

// 4. Core service consumes all contributions
@injectable()
export class MyManager {
    constructor(
        @inject(ContributionProvider) @named(MyContribution)
        private readonly contributions: ContributionProvider<MyContribution>
    ) {}
    
    initialize(): void {
        for (const contrib of this.contributions.getContributions()) {
            contrib.configure();
        }
    }
}

Service Factories

Create services with runtime parameters:

bind('ServiceFactory').toFactory(context => 
    (config: ServiceConfig) => {
        const service = context.container.get(ServiceImpl);
        service.configure(config);
        return service;
    }
);

Types

// InversifyJS types re-exported from Theia
type ServiceIdentifier<T = any> = interfaces.ServiceIdentifier<T>;
type Bind = interfaces.Bind;
type Container = interfaces.Container;
type ContainerModule = interfaces.ContainerModule;

interface Newable<T> {
    new (...args: any[]): T;
}

interface Abstract<T> {
    prototype: T;
}

Install with Tessl CLI

npx tessl i tessl/npm-theia--core

docs

application-framework.md

commands.md

dependency-injection.md

events-messaging.md

index.md

keybindings.md

menus.md

preferences-configuration.md

resources-files.md

widgets-ui.md

tile.json