Chinese

๐ŸŽช CircusRing

CircusRing is a lightweight and flexible dependency injection container for Flutter, making object, lifecycle, and component relationship management intuitive.

โœจ Features

  • ๐Ÿงฉ Multiple Registration Methods:
    • Singleton (immediate or lazy)
    • Asynchronous singleton
    • Factory mode (new instance each time)
    • "fenix" mode to automatically recreate instances
  • ๐Ÿ”„ Dependency Management:
    • Explicitly bind dependencies between components
    • Prevent removal of components that are still depended upon
    • Automatically clean up resources when components are removed
  • ๐Ÿ” Flexible Lookup:
    • Lookup by type (with optional tag)
    • Supports both synchronous and asynchronous lookup
    • Lookup by Tag only is also supported
  • โ™ป๏ธ Resource Management:
    • Automatically handle Disposable or ChangeNotifier
    • Supports asynchronous release via AsyncDisposable

๐Ÿ“ How to Use

๐ŸŒ Global Access

CircusRing is a global singleton. You can easily access it via Circus or Ring:

import 'package:joker_state/circus_ring.dart';

final instance = Circus.find<T>();
final instance = Ring.find<T>();

๐Ÿ“ฅ Register Dependencies

CircusRing provides multiple registration methods. You can even specify an alias, which is useful for architectural patterns.

// Simple singleton registration, returns the instance directly
// Yes, you can use it directly like this
// final repository = Circus.hire<UserRepository>();
Circus.hire(UserRepository());

// Register multiple instances of the same type with tags, suitable for multi-flavor development
Circus.hire<ApiClient>(ProductionApiClient(), tag: 'prod');
Circus.hire<ApiClient>(MockApiClient(), tag: 'test');

// Lazy singleton
Circus.hireLazily<Database>(() => Database.initialize());

// Asynchronous singleton
Circus.hireLazilyAsync<NetworkService>(() async => await NetworkService.initialize());

// Factory mode
Circus.contract<UserModel>(() => UserModel());

// "fenix" mode to automatically recreate instances
Circus.hireLazily<UserModel>(() => UserModel(), fenix: true);

// "alias" mode, pass the `Type` you want as an alias, CircusRing will handle everything for you
Circus.hire<UserRepository>(UserRepositoryImpl(), alias: UserRepository);

๐Ÿ”Ž Lookup Dependencies

CircusRing makes it easy to find registered dependencies, all based on a Map, so it's extremely fast!

// Get a singleton directly
final userRepo = Circus.find<UserRepository>();

// Get a singleton with a tag
final apiClient = Circus.find<ApiClient>('prod');

// Lazy singleton
final db = Circus.find<Database>();

// Asynchronous singleton
final networkService = await Circus.findAsync<NetworkService>();

// Safe lookup (returns null if not found)
final maybeRepo = Circus.tryFind<UserRepository>();

// Lookup by Tag
final client = Circus.findByTag('mockClient');

// Safe Tag lookup, returns null if not found
final maybeClient = Circus.tryFindByTag('mockClient');

๐Ÿ”— Bind Dependencies

CircusRing provides the bindDependency method to bind dependencies, ensuring that dependent objects are not accidentally removed.

// Make UserRepository depend on ApiClient
Circus.bindDependency<UserRepository, ApiClient>();
// As long as UserRepository exists, ApiClient will not be removed

๐Ÿงน Resource Cleanup

CircusRing provides various cleanup methods, including both synchronous and asynchronous cleanup, if you want your dependencies can be automatically disposed when removed, please let your dependencies implement Disposable or AsyncDisposable.

// Remove standard Disposable (triggers dispose)
Circus.fire<UserRepository>();

// Asynchronous removal of AsyncDisposable (triggers async dispose)
await Circus.fireAsync<NetworkService>();

// Remove all dependencies, including asynchronous cleanup
await Circus.fireAll();

โš™๏ธ Friendly Debug Features

By default, CircusRing uses kDebugMode to control debug message output, but you can also control it via enableLogs.

Circus.enableLogs = true; // Enable debug messages
Circus.enableLogs = false; // Disable debug messages

Libraries

circus_ring