dart_service_provider 1.1.0
dart_service_provider: ^1.1.0 copied to clipboard
A services dependency provider, like dependency inject, easy to learn and easy to use.
dart_service_provider #
A services dependency provider, like dependency inject, easy to learn and easy to use.
Features #
Provide services life time control with singleton, scoped, transient.
Getting started #
void main() {
final services = ServiceCollection()
// add the default logging services
..addLogging()
..addSingleton<IMySingletonService, MySingletonService>((_) => MySingletonService())
..addScoped<IMyScopedService, MyScopedService>((_) => MyScopedService())
..addTransient<IMyTransientService, MyTransientService>((_) => MyTransientService())
..addScoped<MyScopedDependencyService, MyScopedDependencyService>(
(p) =>
MyScopedDependencyService(
singletonService: p.getRequiredService<IMySingletonService>(),
scopedService: p.getRequiredService<IMyScopedService>(),
transientService: p.getRequiredService<IMyTransientService>(),
),
);
final serviceProvider = services.buildServiceProvider();
final singletonService = serviceProvider.getRequiredService<IMySingletonService>();
final transientService = serviceProvider.getRequiredService<IMyTransientService>();
// Scoping
final scope = serviceProvider.createScope();
final singletonService2 = scope.serviceProvider.getRequiredService<IMySingletonService>();
assert(identical(singletonService, singletonService2));
final scopedService = scope.serviceProvider.getRequiredService<IMyScopedService>();
final scopedService2 = scope.serviceProvider.getRequiredService<IMyScopedService>();
assert(identical(scopedService, scopedService2));
final transientService2 = scope.serviceProvider.getRequiredService<IMyTransientService>();
assert(!identical(transientService, transientService2));
// Always dispose the scope when you don't need it anymore.
// This will cleanup any resources use by this scope and the services in this scope.
// There is a `disposeAsync()` method for asynchronous calls.
// Note that: `dispose` method from interface `IDisposable` and `disposeAsync` from interface `IAsyncDisposable`
// Any services that it implements `IDisposable` or `IAsyncDisposable` and constructed by `IServiceProvider` will be disposed when its life is end automatically.
scope.dispose();
// Always dispose the ServiceProvider when you don't need it anymore.
// There also is a `disposeAsync()` method
serviceProvider.dispose();
}
abstract interface class IMySingletonService implements IDisposable {}
class MySingletonService implements IMySingletonService {
MySingletonService() {
print("MySingletonService $hashCode constructing");
}
@override
void dispose() {
print("MySingletonService $hashCode disposing");
}
}
abstract interface class IMyScopedService implements IAsyncDisposable {}
class MyScopedService implements IMyScopedService {
MyScopedService() {
print("MyScopedService $hashCode constructing");
}
@override
Future<void> disposeAsync() {
print("MyScopedService $hashCode disposing asynchronous");
return Future<void>.value();
}
}
abstract interface class IMyTransientService implements IDisposable {}
class MyTransientService implements IMyTransientService {
MyTransientService() {
print("MyTransientService $hashCode constructing");
}
@override
void dispose() {
print("MyTransientService $hashCode disposing");
}
}
class MyScopedDependencyService {
final IMySingletonService singletonService;
final IMyScopedService scopedService;
final IMyTransientService transientService;
MyScopedDependencyService(
{required this.singletonService, required this.scopedService, required this.transientService}) {
print("MyDependencyService $hashCode constructing with "
"IMySingletonService ${singletonService.hashCode}, "
"IMyScopedService ${scopedService.hashCode}, "
"IMyTransientService ${transientService.hashCode}");
}
}
Usage #
void main() {
final services = ServiceCollection();
services.addSingleton<MyService, MyService>((_) => MyService());
final rootProvider = services.buildServiceProvider();
final myService = rootProvider.getRequiredService<MyService>();
// myService.foo()
}
class MyService {}
Logging #
Enable default logging
final services = ServiceCollection()
// add the default logging services
..addLogging();
Custom logging:
final services = ServiceCollection()
// add the default logging services
..addLogging((loggingBuilder) {
// Custom your logging services
});
How to custom logging services:
- Implement
ILoggerFactoryinterface, then calladdLoggingextension method onServiceCollection, Specify theconfigargument. - Optional implement
ILoggerandILogger4interfaces, implementILogger4is recommended. - If you implementations does not need
LoggerOptionsservice, please call theLoggingBuilderExtensions.removeOptionsextension method to delete it.
Environment #
Provide environment service.
void main() {
final services = ServiceCollection();
// Add environment service
services.addEnvironment<Evironment>(Environment(name: Environments.production));
final provider = services.buildServiceProvider();
final env = provider.getRequiredService<IEnvironment>();
print(env.isProduction); // true
}
You can detect the environment and change the application behavior at runtime.
Additional information #
If you have any issues or suggests please redirect to repo or send an email to me.
Flutter #
In flutter, you can use flutter_service_provider.
Todo #
Use annotations and code generator to support real Dependency inject.