Skip to content

singleton

awekrx edited this page May 29, 2026 · 1 revision

singleton

Import

import { singleton } from '@dev-suite/decorators/singleton'

Category

  • class

Use Case

Guarantee a single shared instance (or keyed shared instances) for a class.

Replaces

  • Hand-written static getInstance implementations
  • Duplicate singleton caching code in multiple services

Example 1

Without decorator

class ConfigStore {
  private static instance: ConfigStore | null = null;

  static getInstance() {
    if (!ConfigStore.instance) {
      ConfigStore.instance = new ConfigStore();
    }
    return ConfigStore.instance;
  }

  private constructor() {}
}

With decorator

import { singleton } from '@dev-suite/decorators/singleton';

@singleton()
class ConfigStore {
  constructor() {}
}

Why better

  • Removes repetitive static singleton plumbing
  • Keeps class shape normal and testable

Example 2

Without decorator

class TenantCache {
  private static byTenant = new Map<string, TenantCache>();

  static getForTenant(tenantId: string) {
    if (!TenantCache.byTenant.has(tenantId)) {
      TenantCache.byTenant.set(tenantId, new TenantCache(tenantId));
    }
    return TenantCache.byTenant.get(tenantId)!;
  }

  constructor(private readonly tenantId: string) {}
}

With decorator

import { singleton } from '@dev-suite/decorators/singleton';

@singleton({ keyResolver: ([tenantId]) => String(tenantId) })
class TenantCache {
  constructor(private readonly tenantId: string) {}
}

Why better

  • Supports keyed singletons with one reusable policy
  • Eliminates custom map management per class

Clone this wiki locally