Zooper.Bee 3.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Zooper.Bee --version 3.1.0
                    
NuGet\Install-Package Zooper.Bee -Version 3.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Zooper.Bee" Version="3.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zooper.Bee" Version="3.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Zooper.Bee" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Zooper.Bee --version 3.1.0
                    
#r "nuget: Zooper.Bee, 3.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=Zooper.Bee&version=3.1.0
                    
Install Zooper.Bee as a Cake Addin
#tool nuget:?package=Zooper.Bee&version=3.1.0
                    
Install Zooper.Bee as a Cake Tool

Zooper.Bee

<img src="icon.png" alt="Zooper.Bee Logo" width="120" align="right"/>

NuGet Version License: MIT

A flexible and powerful workflow library for .NET that allows you to define complex business processes with a fluent API.

Overview

Zooper.Bee lets you create workflows that process requests and produce either successful results or meaningful errors. The library uses a builder pattern to construct workflows with various execution patterns including sequential, conditional, parallel, and detached operations.

Key Concepts

  • Workflow: A sequence of operations that process a request to produce a result or error
  • Request: The input data to the workflow
  • Payload: Data that passes through and gets modified by workflow activities
  • Success: The successful result of the workflow
  • Error: The errors result if the workflow fails

Installation

dotnet add package Zooper.Bee

Getting Started

// Define a simple workflow
var workflow = new WorkflowBuilder<Request, Payload, SuccessResult, ErrorResult>(
    // Factory function that creates the initial payload from the request
    request => new Payload { Data = request.Data },

    // Selector function that creates the success result from the final payload
    payload => new SuccessResult { ProcessedData = payload.Data }
)
.Validate(request =>
{
    // Validate the request
    if (string.IsNullOrEmpty(request.Data))
        return Option<ErrorResult>.Some(new ErrorResult { Message = "Data is required" });

    return Option<ErrorResult>.None;
})
.Do(payload =>
{
    // Process the payload
    payload.Data = payload.Data.ToUpper();
    return Either<ErrorResult, Payload>.FromRight(payload);
})
.Build();

// Execute the workflow
var result = await workflow.Execute(new Request { Data = "hello world" }, CancellationToken.None);
if (result.IsRight)
{
    Console.WriteLine($"Success: {result.Right.ProcessedData}"); // Output: Success: HELLO WORLD
}
else
{
    Console.WriteLine($"Error: {result.Left.Message}");
}

Building Workflows

Basic Operations

Validation

Validates the incoming request before processing begins.

// Asynchronous validation
.Validate(async (request, cancellationToken) =>
{
    var isValid = await ValidateAsync(request, cancellationToken);
    return isValid ? Option<ErrorResult>.None : Option<ErrorResult>.Some(new ErrorResult());
})

// Synchronous validation
.Validate(request =>
{
    var isValid = Validate(request);
    return isValid ? Option<ErrorResult>.None : Option<ErrorResult>.Some(new ErrorResult());
})
Activities

Activities are the building blocks of a workflow. They process the payload and can produce either a success (with the modified payload) or an error.

// Asynchronous activity
.Do(async (payload, cancellationToken) =>
{
    var result = await ProcessAsync(payload, cancellationToken);
    return Either<ErrorResult, Payload>.FromRight(result);
})

// Synchronous activity
.Do(payload =>
{
    var result = Process(payload);
    return Either<ErrorResult, Payload>.FromRight(result);
})

// Multiple activities
.DoAll(
    payload => DoFirstThing(payload),
    payload => DoSecondThing(payload),
    payload => DoThirdThing(payload)
)
Conditional Activities

Activities that only execute if a condition is met.

.DoIf(
    payload => payload.ShouldProcess, // Condition
    payload =>
    {
        // Activity that only executes if the condition is true
        payload.Data = Process(payload.Data);
        return Either<ErrorResult, Payload>.FromRight(payload);
    }
)

Advanced Features

Groups

Organize related activities into logical groups. Groups can have conditions and always merge their results back to the main workflow.

.Group(
    payload => payload.ShouldProcessGroup, // Optional condition
    group => group
        .Do(payload => FirstActivity(payload))
        .Do(payload => SecondActivity(payload))
        .Do(payload => ThirdActivity(payload))
)
Contexts with Local State

Create a context with the local state that is accessible to all activities within the context. This helps encapsulate related operations.

.WithContext(
    null, // No condition, always execute
    payload => new LocalState { Counter = 0 }, // Create local state
    context => context
        .Do((payload, state) =>
        {
            state.Counter++;
            return (payload, state);
        })
        .Do((payload, state) =>
        {
            payload.Result = $"Counted to {state.Counter}";
            return (payload, state);
        })
)
Parallel Execution

Execute multiple groups of activities in parallel and merge the results.

.Parallel(
    null, // No condition, always execute
    parallel => parallel
        .Group(group => group
            .Do(payload => { payload.Result1 = "Result 1"; return payload; })
        )
        .Group(group => group
            .Do(payload => { payload.Result2 = "Result 2"; return payload; })
        )
)
Detached Execution

Execute activities in the background without waiting for their completion. Results from detached activities are not merged back into the main workflow.

.Detach(
    null, // No condition, always execute
    detached => detached
        .Do(payload =>
        {
            // This runs in the background
            LogActivity(payload);
            return payload;
        })
)
Parallel Detached Execution

Execute multiple groups of detached activities in parallel without waiting for completion.

.ParallelDetached(
    null, // No condition, always execute
    parallelDetached => parallelDetached
        .Detached(detached => detached
            .Do(payload => { LogActivity1(payload); return payload; })
        )
        .Detached(detached => detached
            .Do(payload => { LogActivity2(payload); return payload; })
        )
)
Finally Block

Activities that always execute, even if the workflow fails.

.Finally(payload =>
{
    // Cleanup or logging
    CleanupResources(payload);
    return Either<ErrorResult, Payload>.FromRight(payload);
})

Advanced Patterns

Error Handling

.Do(payload =>
{
    try
    {
        var result = RiskyOperation(payload);
        return Either<ErrorResult, Payload>.FromRight(result);
    }
    catch (Exception ex)
    {
        return Either<ErrorResult, Payload>.FromLeft(new ErrorResult { Message = ex.Message });
    }
})

Conditional Branching

Use conditions to determine which path to take in a workflow.

.Group(
    payload => payload.Type == "TypeA",
    group => group
        .Do(payload => ProcessTypeA(payload))
)
.Group(
    payload => payload.Type == "TypeB",
    group => group
        .Do(payload => ProcessTypeB(payload))
)

Dependency Injection Integration

Zooper.Bee integrates seamlessly with .NET's dependency injection system. You can register all workflow components with a single extension method:

// In Startup.cs or Program.cs
services.AddWorkflows();

This will scan all assemblies and register:

  • All workflow validations
  • All workflow activities
  • All concrete workflow classes (classes ending with "Workflow")

You can also register specific components:

// Register only validations
services.AddWorkflowValidations();

// Register only activities
services.AddWorkflowActivities();

// Specify which assemblies to scan
services.AddWorkflows(new[] { typeof(Program).Assembly });

// Specify service lifetime (Singleton, Scoped, Transient)
services.AddWorkflows(lifetime: ServiceLifetime.Singleton);

Performance Considerations

  • Use Parallel for CPU-bound operations that can benefit from parallel execution
  • Use Detach for I/O operations that don't affect the main workflow
  • Be mindful of resource contention in parallel operations
  • Consider using WithContext to maintain state between related activities

Best Practices

  1. Keep activities small and focused on a single responsibility
  2. Use descriptive names for your workflow methods
  3. Group related activities together
  4. Handle errors at appropriate levels
  5. Use Finally for cleanup operations
  6. Validate requests early to fail fast
  7. Use contextual state to avoid passing too many parameters

License

MIT License (Copyright details here)

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Zooper.Bee:

Package Downloads
Zooper.Bee.MediatR

A .NET library for building robust, functional workflows and processing pipelines.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.3.0 175 4/24/2025
3.2.1 164 4/24/2025
3.2.0 152 4/24/2025
3.1.0 130 4/23/2025
3.0.0 155 4/21/2025
2.2.0 148 4/21/2025
2.1.0 152 4/21/2025
2.0.0 76 4/19/2025
1.0.0 145 4/18/2025