singleton_manager 2.1.0 copy "singleton_manager: ^2.1.0" to clipboard
singleton_manager: ^2.1.0 copied to clipboard

High-performance singleton manager for Dart with DI annotations and lazy loading.

singleton_manager #

Pub Version

A minimal, zero-dependency dependency-injection registry for Dart: RegistryManager, the IRegistry interface it implements, and the @dependencyInjectable annotation used by singleton_manager_generator to write factory constructors for you.

Features #

  • Type-safe: generic getInstance<T>() / connectInstance<Interface, Impl>()
  • Zero dependencies: no external package dependencies at runtime
  • Lazy: a connected factory runs once, the first time its type is resolved; the result is then cached
  • Per-key registration: register multiple instances of the same type under different string keys (default key: 'default')
  • Code generation ready: annotate a class with @dependencyInjectable, let the generator write its dependencyInjectionFactory()
  • Pure Dart: no platform-specific code, works on VM, Web, and Flutter

Installation #

Add to your pubspec.yaml:

dependencies:
  singleton_manager: ^2.0.0

Quick Start #

import 'package:singleton_manager/singleton_manager.dart';

abstract class ILogger {
  void log(String message);
}

class ConsoleLogger implements ILogger {
  @override
  void log(String message) => print(message);
}

void main() {
  final registry = RegistryManager.instance;

  // Connect an interface to a factory — invoked lazily, once, on first access.
  registry.connectInstance<ILogger, ConsoleLogger>(() => ConsoleLogger());

  // Resolve it (same cached instance every time after the first call).
  final logger = registry.getInstance<ILogger>();
  logger.log('Hello from ConsoleLogger!');
}

The IRegistry API #

abstract class IRegistry {
  /// Returns the instance connected to [InterfaceType] under [key], creating
  /// it via its connected factory on first access. Throws
  /// `RegistryNotFoundError` if nothing is connected.
  InterfaceType getInstance<InterfaceType>({String key = 'default'});

  /// Same as [getInstance] but returns `null` instead of throwing.
  InterfaceType? getInstanceNullable<InterfaceType>({String key = 'default'});

  /// Connects [InterfaceType] to a concrete [InstanceType] via [factory].
  /// The factory runs once, the first time [getInstance] (or
  /// [getInstanceNullable]) is called for this (type, key) pair; the result
  /// is cached and reused after that.
  void connectInstance<InterfaceType, InstanceType extends InterfaceType>(
    InstanceType Function() factory, {
    String key = 'default',
  });
}

RegistryManager is a singleton implementation of IRegistry, accessed via RegistryManager.instance.

Per-key registration #

Use key to keep more than one instance of the same type — e.g. environment-specific connections:

final registry = RegistryManager.instance;

registry.connectInstance<IDbConnection, PostgresConnection>(
  () => PostgresConnection('postgres://prod'),
  key: 'prod',
);
registry.connectInstance<IDbConnection, PostgresConnection>(
  () => PostgresConnection('postgres://dev'),
  key: 'dev',
);

final prod = registry.getInstance<IDbConnection>(key: 'prod');
final dev = registry.getInstance<IDbConnection>(key: 'dev');

Error handling #

Situation Result
getInstance<T>() and nothing was connected/set for (T, key) throws RegistryNotFoundError
getInstanceNullable<T>() and nothing was connected/set for (T, key) returns null

Code generation with @dependencyInjectable #

Annotate a class and run singleton_manager_generator to have its dependencyInjectionFactory() written for you, instead of hand-writing the constructor call and its RegistryManager lookups:

@dependencyInjectable
class OrderService implements IOrderService {
  OrderService(this._repository, {IClock? clock});

  final IOrderRepository _repository;
}

See singleton_manager_generator for how the generator maps constructor parameters to getInstance/ getInstanceNullable calls, and for the --registry-output flag that also generates a registerAllSingletons() wiring function.

Examples #

See the examples directory for complete, runnable examples:

  • 1_basic_registry.dart: RegistryManager, connectInstance, getInstance, getInstanceNullable
  • 2_dependency_injection_factory.dart: @dependencyInjectable and the generated dependencyInjectionFactory()
cd packages/singleton_manager
dart run example/1_basic_registry.dart
dart run example/2_dependency_injection_factory.dart

Documentation #

For more information, see the main project documentation.

Contributing #

See CONTRIBUTING.md for contribution guidelines.

License #

MIT License - see LICENSE file for details.

0
likes
0
points
570
downloads

Publisher

unverified uploader

Weekly Downloads

High-performance singleton manager for Dart with DI annotations and lazy loading.

Repository (GitHub)
View/report issues

Topics

#singleton #pattern #dependency-injection #service-locator #resource-management

License

unknown (license)

Dependencies

index_generator

More

Packages that depend on singleton_manager