Singleton<T> class
abstract
Container of singleton instance.
Lazy Singleton
Define Lazy Singleton
class MyLazyService {
/// Factory method that reuse same instance automatically
factory MyLazyService() => Singleton.lazy(() => MyLazyService._());
/// Private constructor
MyLazyService._() {}
/// do something
void doSomething() {}
}
Use Lazy Singleton
MyLazyService().doSomething() // Use the singleton instance
Eager Singleton
Define Eager Singleton
class MyEagerService {
/// Factory method that reuse same instance automatically
factory MyEagerService() => Singleton.get<MyEagerService>();
final MyApi api;
/// Constructor create and register new instance
MyEagerService.initialize(this.api) {
// Register current instance
Singleton.register(this);
}
/// do something
void doSomething() {}
}
Initialize eagerly
void main() {
final appSettings = getAppSettings();
final httpClient = createHttpClient(appSetting);
final api = createMyApi(httpClient);
MyEagerService.initialize(api) // Create and register the the singleton
.doSomething(); // Use the instance
}
Use Eager Singleton
MyEagerService().doSomething(); // Use the singleton instance
Future Singleton
Define the type
Given some other dependants declarations
class AppSettings {
static Future<AppSettings> loadAppSettings() {
// load app settings from somewhere asynchronously
}
}
class HttpClient {
final AppSettings appSettings;
HttpClient(this.appSettings);
}
class MyFutureService {
/// Factory method that reuse same instance automatically
factory MyFutureService() => Singleton.get<MyFutureService>();
static Future<MyFutureService> createInstance() async {
final appSettings = await Singleton<AppSettings>().ensuredInstance();
final httpClient = HttpClient(appSettings);
return MyFutureService._(httpClient);
}
final HttpClient httpClient;
MyFutureService._(this.httpClient);
/// Some method
void doSomething() {}
}
Register future as singleton
Singleton.register
understands future, it register value of future as singleton rather than register future itself
void main() {
// Register AppSettings settings as a future singleton
Singleton.register(AppSettings.loadAppSettings());
// Create and register the the MyService as singleton
Singleton.register(MyFutureService.createInstance());
runApp();
}
Use future singleton
For sure you still can use this approach to consume future singleton.
MyFutureService().doSomething();
It is likely to be okay if when async resource although load asynchronously but will be available fast, such as SharedPreferences
.
But you might encounter StateError
says "singleton is being used before being resolved".
Availability checkpoint
(await Singleton<MyService>().ensuredInstance()).doSomething();
This is a more reliable way, but it removes almost all the benefits to have a sync singleton.
So run following code before usage, such as in main
after register all singleton types
void main() async {
// Register AppSettings settings as a future singleton
Singleton.register(AppSettings.loadAppSettings());
// Create and register the the MyService as singleton
Singleton.register(MyFutureService.createInstance());
await Singleton.ensureInstanceFor([AppSettings, MyFutureService]); // Ensure all singletons are properly initialized
runApp();
}
Then use future singleton in normal way
MyService().doSomething();
Constructors
- Singleton([String? name = null])
-
Get the singleton wrapper for type [T}
factory
-
Singleton.register(FutureOr<
T> value, {String? name = null}) -
Register a singleton
T
with givenvalue
factory -
Singleton.registerLazy(SingletonFactory<
T> factory, {String? name = null}) -
Register or fetch a lazy type singleton wrapper for
T
factory
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- instance → T
-
Get value of singleton
no setter
- key → SingletonKey
-
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
deregister(
[String? name = null]) → void - Deregister singleton from registry
-
ensuredInstance(
) → Future< T> - A FutureOr use to ensure the value is created.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Methods
-
debugPrintAll(
dynamic type) → void -
Prints singletons of given
type
iftype
are omitted, all singletons are printed. -
ensureInstanceFor(
dynamic type) → Future -
Ensure
type
singleton instances exists -
get<
T> ({String? name = null}) → T -
Retrieve an pre-registered singleton For
T
via register. -
lazy<
T> (SingletonFactory< T> factory, {String? name = null}) → T -
Register or fetch a lazy singleton for
T
-
resetAllForTest(
) → void - Debug API to clear all registered singleton to avoid pollution across tests caused by singleton
-
withName<
T> ([String? name = null]) → SingletonKey -
Create SingletonKey for given type
T
andname