diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6cddcaf..331c676 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2.2.0] - 2025-04-25
+
+### Added
+
+- Added unconditional branch with local payload method overload
+ - New `BranchWithLocalPayload` method that doesn't require a condition parameter and always executes
+ - Supports both callback-style API and fluent API patterns: `.BranchWithLocalPayload(localPayloadFactory, branch => { ... })`
+
## [2.1.0] - 2025-04-21
### Added
diff --git a/Directory.Build.props b/Directory.Build.props
index 56d06cd..e941de7 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -13,7 +13,7 @@
A .NET library for building robust, functional workflows and processing pipelines.
- 2.1.0
+ 2.2.0
true
diff --git a/Zooper.Bee.Tests/BranchWithLocalPayloadTests.cs b/Zooper.Bee.Tests/BranchWithLocalPayloadTests.cs
index 0cbfa7f..2febd21 100644
--- a/Zooper.Bee.Tests/BranchWithLocalPayloadTests.cs
+++ b/Zooper.Bee.Tests/BranchWithLocalPayloadTests.cs
@@ -408,4 +408,50 @@ public async Task BranchWithLocalPayload_UnconditionalBranch_AlwaysExecutes()
result.Right.ProcessingResult.Should().Be("Processed with default customization");
result.Right.CustomizationDetails.Should().Be("Default customization");
}
+
+ [Fact]
+ public async Task BranchWithLocalPayload_UnconditionalBranchFluentApi_AlwaysExecutes()
+ {
+ // Arrange
+ var workflow = new WorkflowBuilder(
+ request => new ProductPayload(request.Id, request.Name, request.Price, request.NeedsCustomProcessing),
+ payload => new ProductResult(
+ payload.Id, payload.Name, payload.FinalPrice,
+ payload.ProcessingResult, payload.CustomizationDetails)
+ )
+ .BranchWithLocalPayload(
+ // Local payload factory only (no condition parameter)
+ _ => new CustomizationPayload(
+ AvailableOptions: new[] { "Default Option" },
+ SelectedOptions: new[] { "Default Option" },
+ CustomizationCost: 5.00m,
+ CustomizationDetails: "Default customization (fluent API)"
+ ),
+ // Use callback pattern instead of fluent API
+ branch => branch.Do((mainPayload, localPayload) =>
+ {
+ var updatedMainPayload = mainPayload with
+ {
+ FinalPrice = mainPayload.Price + localPayload.CustomizationCost,
+ CustomizationDetails = localPayload.CustomizationDetails,
+ ProcessingResult = "Processed with fluent API"
+ };
+
+ return Either.FromRight(
+ (updatedMainPayload, localPayload));
+ })
+ )
+ .Build();
+
+ var request = new ProductRequest(1001, "Test Product", 100.00m, false);
+
+ // Act
+ var result = await workflow.Execute(request);
+
+ // Assert
+ result.IsRight.Should().BeTrue();
+ result.Right.FinalPrice.Should().Be(105.00m); // 100 + 5
+ result.Right.ProcessingResult.Should().Be("Processed with fluent API");
+ result.Right.CustomizationDetails.Should().Be("Default customization (fluent API)");
+ }
}
\ No newline at end of file
diff --git a/Zooper.Bee/WorkflowBuilder.cs b/Zooper.Bee/WorkflowBuilder.cs
index da566c0..332ac1b 100644
--- a/Zooper.Bee/WorkflowBuilder.cs
+++ b/Zooper.Bee/WorkflowBuilder.cs
@@ -282,6 +282,21 @@ public WorkflowBuilder BranchWithLocalPayl
return this;
}
+ ///
+ /// Creates a branch in the workflow with a local payload that always executes.
+ /// This is a convenience method for organizing related activities.
+ ///
+ /// The type of the local branch payload
+ /// The factory function that creates the local payload
+ /// A branch builder that allows adding activities to the branch
+ public BranchWithLocalPayloadBuilder BranchWithLocalPayload(
+ Func localPayloadFactory)
+ {
+ var branch = new BranchWithLocalPayload(_ => true, localPayloadFactory);
+ _branchesWithLocalPayload.Add(branch);
+ return new BranchWithLocalPayloadBuilder(this, branch);
+ }
+
///
/// Creates a branch in the workflow with a local payload that always executes.
/// This is a convenience method for organizing related activities.