A powerful .NET library for building workflows, orchestrating processes, and managing state machines with event-driven architecture.
Magnett Automation Core is a comprehensive .NET library designed to simplify the creation of complex, event-driven applications. It provides a unified approach to workflow orchestration, state management, and process automation that scales from simple business processes to complex microservices architectures.
Traditional Challenges:
- Complex nested if/else statements for business logic
- Difficult-to-maintain state management
- Scattered event handling across applications
- Manual orchestration of distributed processes
- Lack of observability in automated workflows
Our Solution:
- Declarative Workflows: Define business processes as clear, maintainable workflows
- Event-Driven Architecture: Built-in event system for loose coupling and scalability
- State Machine Management: Type-safe state transitions with clear business rules
- Process Orchestration: Coordinate complex multi-step processes automatically
- Built-in Observability: Metrics, logging, and monitoring out of the box
Separation of Concerns: Clear separation between workflow definition and execution Type Safety: Full IntelliSense support with compile-time validation Event-Driven: Reactive architecture that responds to changes and events Observable: Built-in metrics and monitoring for production environments Extensible: Plugin architecture for custom implementations
- Business Process Automation: Automate complex business workflows
- Microservices Orchestration: Coordinate distributed services
- Event-Driven Applications: Build reactive, event-sourced systems
- Workflow Engines: Create custom workflow solutions
- State Management: Manage complex application states
- Integration Patterns: Implement saga patterns and distributed transactions
dotnet add package Magnett.Automation.Core
using Magnett.Automation.Core;
// Create context
var context = Context.Create();
// Define workflow with nodes and transitions
var definition = FlowDefinitionBuilder.Create()
.WithInitialNode<ResetValueNode>(NodeName.Reset)
.OnExitCode(ExitCode.Ok).GoTo(NodeName.SetValue)
.Build()
.WithNode<SetValueNode>(NodeName.SetValue)
.OnExitCode(ExitCode.Assigned).GoTo(NodeName.SumValue)
.Build()
.WithNode<SumValueNode>(NodeName.SumValue)
.Build()
.BuildDefinition();
// Execute workflow
var flow = Flow.Create(FlowRunner.Create(definition, context));
var result = await flow.Run();
For comprehensive examples including:
- Simple Workflow: Basic 3-node workflow with context management
- Saga Pattern: Distributed transaction management
- State Machines: Complex state transitions
- Event-Driven Architecture: EventBus integration
See the Integration Tests directory for complete, working examples.
- π Workflows: Declarative workflow orchestration with async/sync nodes
- π State Machines: Type-safe state management with transitions
- π‘ Events: Event-driven architecture with EventBus and EventStream
- π Metrics: Built-in performance monitoring and observability
- πΎ Context: Shared data storage across workflow components
- π― Type-Safe: Full IntelliSense support with generic types
Magnett Automation Core is built around five core pillars:
Declarative workflow definitions that separate business logic from execution. Define complex processes as a series of connected nodes with clear transitions and error handling.
Type-safe state management with explicit transitions. Define business states and the actions that can transition between them, with compile-time validation.
Event-driven architecture with asynchronous processing. Publish events, register handlers, and build reactive systems that respond to changes in real-time.
Shared data storage that flows through workflows and state machines. Type-safe field definitions with automatic serialization and event emission on changes.
All components work together seamlessly:
- Workflows can emit events and manage state
- State Machines can trigger workflows and emit events
- Events can drive workflow transitions and state changes
- Context provides shared data across all components
// Simple setup with automatic metrics
var eventBus = EventBus.Create(logger);
// Publish events
await eventBus.PublishAsync(new OrderCreatedEvent(orderId));
// Register handlers
eventBus.EventHandlerRegistry.Register<OrderEventHandler>();
// Define states and actions
public class OrderState : Enumeration
{
public static readonly OrderState Pending = new(1, nameof(Pending));
public static readonly OrderState Processing = new(2, nameof(Processing));
public static readonly OrderState Completed = new(3, nameof(Completed));
}
// Create machine definition
var definition = MachineDefinitionBuilder.Create()
.InitialState(OrderState.Pending)
.OnAction(OrderAction.Process).ToState(OrderState.Processing)
.Build()
.AddState(OrderState.Processing)
.OnAction(OrderAction.Complete).ToState(OrderState.Completed)
.Build()
.BuildDefinition();
// Use the machine
var machine = Machine.Create(definition);
machine.Dispatch(OrderAction.Process);
// Create context
var context = Context.Create();
// Define typed fields
var orderIdField = ContextField<int>.Create("OrderId");
var statusField = ContextField<string>.Create("Status");
// Store and retrieve values
context.Store(orderIdField, 12345);
context.Store(statusField, "Processing");
var orderId = context.Value(orderIdField);
var status = context.Value(statusField);
// Define node names
public record NodeName : CommonNamedKey
{
public static readonly NodeName Reset = new("Reset");
public static readonly NodeName Process = new("Process");
private NodeName(string name) : base(name) { }
}
// Define exit codes
public record ExitCode : Enumeration
{
public static readonly ExitCode Success = new(1, nameof(Success));
public static readonly ExitCode Failed = new(2, nameof(Failed));
private ExitCode(int id, string name) : base(id, name) { }
}
// Implement workflow node
public class ProcessOrderNode : Node
{
public ProcessOrderNode(CommonNamedKey key, IEventBus eventBus) : base(key, eventBus) { }
protected override NodeExit Handle(Context context)
{
// Your business logic here
var orderId = context.Value(ContextDefinition.OrderId);
// Process order...
return NodeExit.Completed(ExitCode.Success);
}
}
Built-in metrics collection for monitoring workflow performance:
// Simple setup with automatic metrics
var eventBus = EventBus.Create(logger);
// Access metrics through the event bus
var metricsRegistry = GetMetricsRegistryFromEventBus(eventBus);
var processingTime = metricsRegistry.GetHistogramValues("events.processing.time");
var eventCount = metricsRegistry.GetCounterValue("events.published");
Advanced Configuration:
// Enable metrics manually for advanced scenarios
var metricsRegistry = new MetricsRegistry();
var metricsCollector = new MetricsCollector(metricsRegistry);
var eventBus = EventBus.Create(logger, null, metricsCollector);
// Access metrics
var processingTime = metricsRegistry.GetHistogramValues("events.processing.time");
var eventCount = metricsRegistry.GetCounterValue("events.published");
During workflow execution, the system automatically emits different types of events that you can monitor and handle:
Event | Description | Properties |
---|---|---|
OnNodeInitEvent |
Emitted when a node is initialized | NodeName |
OnNodeExecuteEvent |
Emitted when a node is executed | NodeName |
OnNodeCompletedEvent |
Emitted when a node completes successfully | NodeName , Code , Data |
OnNodeFailedEvent |
Emitted when a node fails | NodeName , Code , Data |
OnNodeCancelledEvent |
Emitted when a node is cancelled | NodeName , Code , Data |
OnNodePausedEvent |
Emitted when a node is paused | NodeName , Code , Data |
Event | Description | Properties |
---|---|---|
OnMachineInit |
Emitted when a state machine is initialized | MachineId |
OnMachineChangeState |
Emitted when a state machine changes state | MachineId , SourceState , TargetState , Action |
Event | Description | Properties |
---|---|---|
OnChangeFieldValueEvent |
Emitted when a context field value changes | FieldName , ValueType , Value , PreviousValue |
// Simple setup with automatic metrics collection
var eventBus = EventBus.Create(logger);
// Register handlers for specific events
eventBus.EventHandlerRegistry.Register<OnNodeExecuteEventHandler>();
eventBus.EventHandlerRegistry.Register<OnMachineChangeStateHandler>();
// Access metrics through the event bus
var metricsRegistry = GetMetricsRegistryFromEventBus(eventBus);
var publishedCount = metricsRegistry.GetCounterValue("events.published");
var processedCount = metricsRegistry.GetCounterValue("events.processed");
var queueSize = metricsRegistry.GetGaugeValue("queue.size");
Alternative: Manual Configuration
// For advanced scenarios, configure metrics manually
var metricsRegistry = new MetricsRegistry();
var metricsCollector = new MetricsCollector(metricsRegistry);
var eventBus = EventBus.Create(logger, null, metricsCollector);
// Monitor metrics in real-time
var publishedCount = metricsRegistry.GetCounterValue("events.published");
var processedCount = metricsRegistry.GetCounterValue("events.processed");
var queueSize = metricsRegistry.GetGaugeValue("queue.size");
- Declarative Approach: Define complex processes in clear, maintainable code
- Type Safety: Catch errors at compile time, not runtime
- IntelliSense Support: Full IDE support with autocomplete and documentation
- Rapid Development: Build complex workflows in minutes, not hours
- Production Tested: Battle-tested in real-world applications
- High Performance: Optimized for throughput and low latency
- Observable: Built-in metrics, logging, and monitoring
- Scalable: Designed for high-concurrency scenarios
- Clean API: Intuitive, fluent interfaces
- Comprehensive Examples: Complete working examples in integration tests
- Active Community: Responsive maintainers and growing community
- Well Documented: Extensive documentation and examples
- Microservices Orchestration: Coordinate complex service interactions
- Business Process Automation: Automate multi-step business workflows
- Event-Driven Applications: Build reactive systems with event sourcing
- State Management: Manage complex application states
- Workflow Engines: Create custom workflow solutions
- Integration Patterns: Implement saga patterns and distributed transactions
- .NET 6.0 or later
- Microsoft.Extensions.Logging
- Microsoft.Extensions.Caching.Memory
- Integration Tests - Complete working examples
- Unit Tests - API usage examples
- Release Notes
We welcome contributions! Here's how you can help:
- π Report Issues: Found a bug? Use our bug report template
- β¨ Suggest Features: Have an idea? Use our feature request template
- β Ask Questions: Need help? Use our support template
- π¬ Share Feedback: Want to discuss? Use our feedback template
- π§ Submit PRs: Want to contribute code? Check our contributing guide
- β Star the Project: Show your support by starring this repository
git clone https://github.com/LHPiney/magnett-automation-core.git
cd magnett-automation-core
dotnet restore
dotnet build
dotnet test
# Run integration tests for complete examples
dotnet test test/Magnett.Automation.Core.IntegrationTest/
- High Performance: Optimized for throughput and low latency
- Memory Efficient: Minimal allocations and garbage collection pressure
- Scalable: Designed for high-concurrency scenarios
- Observable: Built-in metrics and monitoring capabilities
- π― Production Ready: Battle-tested in real-world applications
- π Type Safe: Compile-time safety with full IntelliSense support
- π¦ Lightweight: Minimal dependencies, maximum functionality
- π Extensible: Plugin architecture for custom implementations
- π Observable: Built-in metrics and event-driven monitoring
- π Fast: Optimized for performance and scalability
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with β€οΈ by the Magnett team
- Inspired by modern workflow orchestration patterns
- Community-driven development and feedback
Ready to build amazing workflows? Get started now!