All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Railway.Create()— two-phase builder factory that enforces a clear separation between the guard/validation phase and the step execution phase at the type-system levelRailway.Create(factory, selector, guards, steps)— with guardsRailway.Create(factory, selector, steps)— without guards (convenience overload)- Parameterless variants (
Func<TPayload>factory) for railways with no request input - New
RailwayGuardBuilder<...>— only exposesGuard()andValidate() - New
RailwayStepsBuilder<...>— only exposesDo(),DoIf(),DoAll(),Group(),WithContext(),Detach(),Parallel(),ParallelDetached(),Finally(), andBuild()
- Registration-order bug:
Group(),WithContext(),Detach(),Parallel(), andParallelDetached()steps now execute in the exact order they were registered, interleaved correctly withDo()steps. Previously allDo()steps ran before all feature steps regardless of registration order.
RailwayBuilder<TRequest, TPayload, TSuccess, TError>— useRailway.Create()insteadRailwayBuilderFactory— useRailway.Create()instead
- Renamed all
Workflowclasses toRailwayto better reflect the railway-oriented programming patternWorkflow<TRequest, TSuccess, TError>->Railway<TRequest, TSuccess, TError>WorkflowBuilder<...>->RailwayBuilder<...>WorkflowBuilderFactory->RailwayBuilderFactoryCreateWorkflow<...>()->CreateRailway<...>()IWorkflowStep->IRailwayStepIWorkflowValidation->IRailwayValidationIWorkflowGuard->IRailwayGuardAddWorkflows()->AddRailways()AddWorkflowSteps()->AddRailwaySteps()
- All old
Workflownames are preserved as[Obsolete]shims for backward compatibility - Updated all example files to use the new Railway terminology
- New
IWorkflowStepandIWorkflowStep<TPayload, TError>interfaces to replaceIWorkflowActivity - New
IWorkflowStepsandIWorkflowSteps<TPayload, TError>interfaces to replaceIWorkflowActivities - New
WorkflowStepsExtensionsclass withAddWorkflowSteps*extension methods for dependency injection
IWorkflowActivityandIWorkflowActivity<TPayload, TError>— useIWorkflowStep/IWorkflowStep<TPayload, TError>insteadIWorkflowActivitiesandIWorkflowActivities<TPayload, TError>— useIWorkflowSteps/IWorkflowSteps<TPayload, TError>insteadWorkflowActivitiesExtensionsclass and allAddWorkflowActivities*methods — useWorkflowStepsExtensionsandAddWorkflowSteps*instead
-
All existing code using the deprecated types and methods will continue to work but will show deprecation warnings
-
To migrate, replace:
services.AddWorkflowActivities();
With:
services.AddWorkflowSteps();
And replace interface implementations:
public class MyStep : IWorkflowActivity<MyPayload, MyError>
With:
public class MyStep : IWorkflowStep<MyPayload, MyError>
-
New guards feature for verifying workflow execution requirements
- Added
Guardmethods to check if a workflow can be executed - Guards run after validations and before Activities and provide early termination
- Added
-
New component interfaces for dependency injection and workflow composition
- Added
IWorkflowGuardandIWorkflowGuard<TRequest, TError>interfaces - Added
IWorkflowGuardsandIWorkflowGuards<TRequest, TError>interfaces
- Added
-
New extension methods for registering guards with dependency injection
- Added
AddWorkflowGuards()for registering workflow guards
- Added
- Code readability improvements in
WorkflowBuilder
- New project
Zooper.Bee.MediatRfor MediatR integration - New
WorkflowHandler<TRequest, TPayload, TSuccess, TError>base class for defining workflows as MediatR handlers - Support for creating dedicated workflow classes that integrate with MediatR's request/response pattern
-
Added new extension methods for dependency injection:
AddWorkflows()- Registers all workflow components (validations, activities, and workflows)AddWorkflowValidations()- Registers workflow validations onlyAddWorkflowActivities()- Registers workflow activities only
-
Added support for automatic assembly scanning to discover workflow components
-
Added the ability to specify service lifetime for workflow registrations
- Complete redesign of the workflow feature API
- New
Groupmethod that groups activities with an optional condition - New
WithContextmethod for isolated contexts with their own local state - New
Detachmethod for executing activities without merging their results back - New
Parallelmethod for parallel execution of multiple groups - New
ParallelDetachedmethod for parallel execution of detached activities
- New
- Better support for nullable conditions - all new methods accept nullable condition
- Clear separation of merged and non-merged execution paths
- Improved naming consistency across the API
- BREAKING CHANGE: Reorganized internal class structure
- Added feature-specific namespaces and folders
- Created a consistent
IWorkflowFeatureinterface for all features
- BREAKING CHANGE: Renamed
BranchtoGroupfor better clarity - BREAKING CHANGE: Renamed
BranchWithLocalPayloadtoWithContextto better express intention
- The old
Branchmethod is now marked as obsolete and will be removed in a future version - The old
BranchWithLocalPayloadmethod is now marked as obsolete and will be removed in a future version
-
All existing code using the deprecated methods will continue to work but will show deprecation warnings
-
To migrate, replace:
.Branch(condition, branch => branch.Do(...))
With:
.Group(condition, group => group.Do(...))
And replace:
.BranchWithLocalPayload(condition, factory, branch => branch.Do(...))
With:
.WithContext(condition, factory, context => context.Do(...))
- Added unconditional branch with local payload method overload
- New
BranchWithLocalPayloadmethod that doesn't require a condition parameter and always executes - Supports both callback-style API and fluent API patterns:
.BranchWithLocalPayload(localPayloadFactory, branch => { ... })
- New
- Added support for branches with isolated local payloads
- New
BranchWithLocalPayloadmethod that allows branches to use their own payload type - Activities within these branches can access and modify both the main payload and the local payload
- Local payloads are isolated to their branch and don't affect other parts of the workflow
- New
- Added an improved API for workflow branching that doesn't require
.EndBranch()calls- New
Branchmethod overload that accepts a configuration action:.Branch(condition, branchBuilder => { ... }) - New
Branchmethod overload without a condition for logical grouping of activities:.Branch(branchBuilder => { ... })
- New
- BREAKING CHANGE: Fixed XML documentation warnings in
WorkflowBuilder- Removed unnecessary param tags from class-level documentation
- The
.EndBranch()method inBranchBuilderis now considered deprecated and will be removed in a future version- Use the new callback-style API for defining branches instead
-
All existing code using the fluent API with
.EndBranch()continues to work, but will produce a deprecation warning -
To migrate, replace:
.Branch(condition) .Do(action1) .Do(action2) .EndBranch()
With:
.Branch(condition, branch => branch .Do(action1) .Do(action2) )
- Initial release of Zooper.Bee workflow library
- Core workflow builder with fluent API
- Support for activities, validations, and conditional branches
- Finally blocks that always execute