ActorSrcGen.Abstractions 0.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package ActorSrcGen.Abstractions --version 0.3.0
NuGet\Install-Package ActorSrcGen.Abstractions -Version 0.3.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="ActorSrcGen.Abstractions" Version="0.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ActorSrcGen.Abstractions --version 0.3.0
#r "nuget: ActorSrcGen.Abstractions, 0.3.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.
// Install ActorSrcGen.Abstractions as a Cake Addin
#addin nuget:?package=ActorSrcGen.Abstractions&version=0.3.0

// Install ActorSrcGen.Abstractions as a Cake Tool
#tool nuget:?package=ActorSrcGen.Abstractions&version=0.3.0

Welcome to ActorSrcGen

ActorSrcGen is a C# Source Generator allowing the conversion of simple C# classes into Dataflow compatible pipelines supporting the actor model.

Where to get it

The source generator can be installed using nuget at ActorSrcGen.

NB. This library is only days old, and will probably change significantly in the weeks ahead. Please treat it as experimental for the time being.

If you notice any issues with the generated code please report them on Github.

What it does

The aim of the source generator is to help you simplify your code. It does that by generating the boilerplate code needed to use TPL Dataflow with a regular class. So you write a simple partial class like this:

[Actor]
public partial class MyWorkflow
{
    [InitialStep(next: "DoTask2")]
    public Task<string> DoTask1(int x)
    {
        Console.WriteLine("DoTask1");
        return Task.FromResult(x.ToString());
    }

    [Step(next: "DoTask3")]
    public Task<string> DoTask2(string x)
    {
        Console.WriteLine("DoTask2");
        return Task.FromResult($"100{x}");
    }

    [LastStep]
    public Task<int> DoTask3(string input)
    {
        Console.WriteLine("DoTask3");
        return Task.FromResult(int.Parse(input));
    }
}

And the source generator will extend it, adding the TPL Dataflow code to wire the methods together:

namespace ActorSrcGen.Abstractions.Playground;
using System.Threading.Tasks.Dataflow;
using Gridsum.DataflowEx;

public partial class MyWorkflow : Dataflow<Int32, Int32>
{
    public MyWorkflow() : base(DataflowOptions.Default)
    {
        _DoTask1 = new TransformManyBlock<Int32, String>(async (Int32 x) => {
            var result = new List<String>();
            try
            {
                result.Add(await DoTask1(x));
            }catch{}
            return result;
        },
            new ExecutionDataflowBlockOptions() {
                BoundedCapacity = 5,
                MaxDegreeOfParallelism = 8
        });
        RegisterChild(_DoTask1);
        _DoTask2 = new TransformManyBlock<String, String>(async (String x) => {
            var result = new List<String>();
            try
            {
                result.Add(await DoTask2(x));
            }catch{}
            return result;
        },
            new ExecutionDataflowBlockOptions() {
                BoundedCapacity = 5,
                MaxDegreeOfParallelism = 8
        });
        RegisterChild(_DoTask2);
        _DoTask3 = new TransformManyBlock<String, Int32>(async (String x) => {
            var result = new List<Int32>();
            try
            {
                result.Add(await DoTask3(x));
            }catch{}
            return result;
        },
            new ExecutionDataflowBlockOptions() {
                BoundedCapacity = 5,
                MaxDegreeOfParallelism = 8
        });
        RegisterChild(_DoTask3);
        _DoTask1.LinkTo(_DoTask2, new DataflowLinkOptions { PropagateCompletion = true });
        _DoTask2.LinkTo(_DoTask3, new DataflowLinkOptions { PropagateCompletion = true });
    }
    TransformManyBlock<Int32, String> _DoTask1;

    TransformManyBlock<String, String> _DoTask2;

    TransformManyBlock<String, Int32> _DoTask3;

    public override ITargetBlock<Int32> InputBlock { get => _DoTask1; }
    public override ISourceBlock<Int32> OutputBlock { get => _DoTask3; }

    public async Task<bool> Post(Int32 input)
    => await InputBlock.SendAsync(input);
} 

Invocation of your class is a straightforward call to post a message to it:

using ActorSrcGen.Abstractions.Playground;

var wf = new MyWorkflow();
if (await wf.Cast(10))
    Console.WriteLine("Called Asynchronously");

var wf2 = new MyWorkflow2();
if (wf2.Call(10))
    Console.WriteLine("Called Synchronously");

await wf2.CompletionTask;

Why Bother?

Writing robust and performant asynchronous and concurrent code in .NET is a laborious process. TPL Dataflow makes it easier - it "provides dataflow components to help increase the robustness of concurrency-enabled applications. This dataflow model promotes actor-based programming by providing in-process message passing for coarse-grained dataflow and pipelining tasks" (see docs). This source generator allows you to take advantage of that model without needing to write a lot of the necessary boilerplate code.

The generated source builds atop DataflowEx for a clean stateful object-oriented wrapper around your pipeline.

With thanks to:

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. 
.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 ActorSrcGen.Abstractions:

Package Downloads
ActorSrcGen

A C# Source Generator to adapt a simple class to allow it to use TPL Dataflow for robust high performance computation

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1 23 4/28/2024
0.3.6 44 4/25/2024
0.3.5 77 4/24/2024
0.3.3 86 4/23/2024
0.3.0 554 11/4/2023
0.2.10 368 10/31/2023