zef_orchestration_core
This Dart library provides a flexible and efficient way to handle and orchestrate requests using a command and query pattern. It's designed to facilitate the separation of command and query operations, enabling clear and maintainable code structures for complex applications.
Features
- Generic Request Handling: Define request handlers that process specific types of requests and return corresponding results.
- Command and Query Separation: Separate handling of command and query operations for clear distinction between actions that change state and those that retrieve data.
- Asynchronous Support: Built-in support for asynchronous operations, enabling non-blocking I/O operations.
- Singleton Orchestrator: Central orchestrator instance to manage command and query handlers, ensuring a single point of orchestration.
Getting Started
Installation
To integrate this library into your Dart or Flutter project, add the following dependency to your pubspec.yaml
file:
dependencies:
your_library_name: latest_version
Quick Start
Initializing the Orchestrator
Before using the Orchestrator
, initialize it:
void main() {
OrchestratorBuilder().build();
}
If you have implemented a custom OrchestratorAdapter
, you should initialize the Orchestrator
with using it:
void main() {
OrchestratorBuilder()
.withAdapter(YourCustomOrchestratorAdapter())
.build();
}
Defining Requests and Handlers
Create your command and query requests along with their respective handlers. Each handler should implement the corresponding abstract handler class:
class SampleCommand extends Command {
// Implementation details
}
class SampleCommandHandler extends CommandHandler<SampleCommand> {
@override
Future<void> call(SampleCommand command) async {
// Command handling logic
}
}
Registering Handlers with the Orchestrator
Register your command and query handlers with the orchestrator to enable their processing:
Orchestrator.I.registerCommandHandler(SampleCommandHandler());
Using the Orchestrator to Send Commands and Queries
Send commands and queries through the orchestrator and handle the results as needed:
await Orchestrator.I.publish(SampleCommand());
// For queries with expected results
var queryResult = await Orchestrator.I.send(SampleQuery());
Registering Handlers with a factory
You can also register your RequestHandler
via a factory, so the instances won't be stored in memory. This can reduce the memory usage, but keep in mind that it can lead the decreased performance when sending or publish a request, as the Orchestrator
tries to resolve an instance.
However if you register your RequestHandler
via dependency injection as a Lazy
, the RequestHandler
instance will be resolved at the first time it is needed. This decreases startup time and memory usage. So we recommend going that way.
Orchestrator.I.registerCommandHandlerFactory(() => SampleCommandHandler());
Note: this is now a factory, which directly returns an instance every time we send the appropriate Command
.
Contributing
Contributions to this library are welcome. Please feel free to submit pull requests or open issues to discuss proposed changes or enhancements.