FluxFlow.Composition 8.0.0-rc.1

This is a prerelease version of FluxFlow.Composition.
dotnet add package FluxFlow.Composition --version 8.0.0-rc.1
                    
NuGet\Install-Package FluxFlow.Composition -Version 8.0.0-rc.1
                    
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="FluxFlow.Composition" Version="8.0.0-rc.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FluxFlow.Composition" Version="8.0.0-rc.1" />
                    
Directory.Packages.props
<PackageReference Include="FluxFlow.Composition" />
                    
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 FluxFlow.Composition --version 8.0.0-rc.1
                    
#r "nuget: FluxFlow.Composition, 8.0.0-rc.1"
                    
#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.
#:package FluxFlow.Composition@8.0.0-rc.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FluxFlow.Composition&version=8.0.0-rc.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=FluxFlow.Composition&version=8.0.0-rc.1&prerelease
                    
Install as a Cake Tool

FluxFlow.Composition

Canonical application definitions, explicit component registration, addressing, validation, link compilation, and code-first runtime ownership. The package is Engine-independent.

Input Shape Preflight

Canonical bindings can declare the destination's existing materializer contract: HasFlowValueInput("Input", node => node.Input, materializer.InputShape). Instance factories use HasFlowValueInput("Input", inputShape). ComponentPortMetadata.InputShape retains this metadata without activating the factory. ComponentDescriptor.ValidateInputShape("Input", sample) returns a structural result, or null when no shape was declared. Runtime domain validation remains inside the destination component. C# and JSON links remain dynamic when the source guarantees no value shape.

Application Shape

{
  "Resources": {},
  "Workflows": {
    "Orders": {
      "Receive": { "Type": "source" },
      "Handle": {
        "Type": "handler",
        "Input": "Receive.Output"
      }
    }
  }
}

Resources, workflows, and components are named by object keys. Components are flat; there are no maintained Composition, Nodes, or root Links wrappers. Addresses are ordinal and case-sensitive. Links support fan-in, fan-out, conditions, cross-workflow addresses, and explicit bounded signal feedback. Ordinary data-processing cycles are rejected.

Code-First Authoring

JSON/configuration and compiled C# are independent authoring sources. They converge at normalization, validation, link compilation, and runtime execution; the C# builder does not serialize or round-trip through JSON.

Create workflow scopes either by return value or by flat fluent capture:

var application = new ApplicationDefinitionBuilder()
    .AddWorkflow("Orders", out var orders)
    .AddWorkflow("Audit", out var audit);

orders
    .AddComponent("Source", OrderComponents.Source, out var source)
    .AddComponent("Review", OrderComponents.Review, out var review)
    .AddComponent("Priority", OrderComponents.Sink, out var priority)
    .AddComponent("Standard", OrderComponents.Sink, out var standard);

audit.AddComponent("Events", OrderComponents.EventCollector, out var events);

source.Output.ConnectTo(review.Input);
review.Output
    .ConnectTo(priority.Input, when: static order => order.Priority)
    .ConnectTo(standard.Input, when: static order => !order.Priority);
review.Events.ConnectTo(events.Input);

var definition = application.Build();
services.AddFluxFlow(definition);

ComponentContract<THandle> and ComponentContract<TOptions,THandle> hold one complete declaration: canonical type, runtime factory and bindings, typed handle, and optional component-specific options factory/apply delegate. Contract construction creates one immutable descriptor but performs no reflection, scanning, service resolution, or runtime activation. Official packages expose contracts through <Family>Components classes, and their retained AddX methods delegate to the same core. Typed handles expose named ports, including explicit Events outputs.

ConnectTo returns the same output handle for fan-out. Workflow Connect is local; application Connect and direct ConnectTo support same-owner cross-workflow links. Conditions may be portable expression strings or synchronous Func<T,bool> predicates. Predicates are definition/revision-owned, require no expression engine, skip error messages, and isolate exceptions to the affected route.

Build() freezes the graph and returns a directly hostable in-memory ApplicationDefinition that owns the exact runtime descriptors introduced by its complete component contracts and the exact executable registrars introduced by its application resource contracts. services.AddFluxFlow(definition) therefore needs no duplicate component or resource-family registration. The UI/designer remains JSON-only, and C# export or serialization is intentionally not part of this API. See docs/39-typed-code-first-authoring.md for custom contracts, condition and revision semantics, and migration guidance.

ApplicationLinkCompiler owns parsing, address resolution, validation, normalization, and deterministic ordering for both sources. Its result exposes executable Links plus resolved portable Declarations for JSON persistence. Code predicates remain executable in-memory links and are not persistence projections. Serialize edited ApplicationLinkDeclarationProjection values with ApplicationLinkCompiler.SerializeDeclarations(...) so hosts and Designer use the same exact Port / Condition grammar. Composition grants no production friend access to Designer or Engine.

ComponentDescriptor declares one canonical type, typed FlowMessage<T> ports, link cardinality, processing capabilities, and an activation delegate. For a JSON or low-level string definition, explicitly register a reusable contract with AddComponent(contract). Author a dynamic runtime-only descriptor through the explicit AddFluxFlowComponents().Advanced.AddDynamicComponent(...) escape hatch. Engine builds one effective immutable ComponentCatalog per candidate from host registrations plus definition-owned descriptors; application validation, link compilation, activation, and Designer metadata consume the same descriptor facts. Errors travel on normal outputs. Application revisions own component and link lifecycle but do not own external resources supplied by the host.

services.AddFluxFlowComponents()
    .Advanced
    .AddDynamicComponent("orders.handle", component =>
    {
        component
            .UseFactory(CreateHandler)
            .HasInput("Input", static node => node.Input)
            .HasOutput("Output", static node => node.Output)
            .HasEvents("Events", static node => node.Events);
    });

This is the advanced/dynamic path, not an additional step after typed AddComponent(name, contract, ...) authoring. UseFactory accepts synchronous node factories and asynchronous ValueTask node factories. Its typed builder makes each port declaration authoritative for both descriptor metadata and the activated Dataflow binding. Selectors run only after activation. HasInput, HasSignalInput, HasOutput, and HasEvents describe existing node members; they do not create duplicate Dataflow ports. HasEvents(name, selector) exposes the selected canonical ISourceBlock<FlowMessage> as a FlowValue output. FlowEvent is an optional code-first builder that serializes into that contract; no adapter node is added to the workflow. Event ports are never injected, and Events is not reserved. Advanced complete-instance factories use UseInstanceFactory, while ComponentNodeActivation<TNode> carries the small optional completion/additional-cleanup case without duplicating ports.

Composition adapters that materialize application resources implement IApplicationResourceRegistrar. Its context exposes the complete definition, revision identity, host services, and revision-owned IServiceCollection. ApplicationResourceContract<THandle> and ApplicationResourceContract<TOptions,THandle> pair one portable resource type, typed handle, explicit options projection, and registrar. Contracts are kept in ApplicationDefinition.ApplicationResourceContracts for compiled C# only and are excluded from canonical JSON. Exact contract/registrar reuse deduplicates; different contracts for one type fail atomically before activation. Canonical keyed DI helpers live in FluxFlow.Composition.DependencyInjection; Engine consumes these low-level contracts without making adapters depend on a hosting package.

Canonical workflow JSON selects an optional semantic Processing profile. Composition maps that profile centrally to capacity, parallelism, and ordering. Direct C# callers may still provide the technical options explicitly; those compatibility settings are not primary workflow or Designer concepts.

ApplicationRuntime waits for all upstreams before completing a shared input, faults fan-in once on the first upstream fault, and attempts all cleanup before aggregating teardown failures.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (24)

Showing the top 5 NuGet packages that depend on FluxFlow.Composition:

Package Downloads
FluxFlow.Engine

Canonical FluxFlow application runtime assembler with transactional revisions, stable addressable ports, conditional routing, system events, and diagnostics.

FluxFlow.Components.Designer

Reusable component metadata and canonical application editing contracts for FluxFlow.

FluxFlow.Composition.Hosting

Optional hosting bridge for FluxFlow.Composition that builds standalone compositions from DI/configuration, starts them with host lifecycle, and resolves adapter-owned keyed resources.

FluxFlow.Fluent

Type-safe, code-first fluent DSL for composing FluxFlow standalone nodes into a runnable graph — Flow.From(source).Then(node).To(sink) with compile-time-checked wiring, branching, and fan-in. Reuses the FluxFlow.Composition runtime.

FluxFlow.Components.Mqtt.Composition

Canonical FluxFlow Composition resources and nodes for provider-neutral MQTT client control, publication, subscriptions, and client events.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.0.0-rc.1 300 9/5/2026
7.0.0-rc.1 438 8/9/2026
6.0.0 933 8/3/2026
1.2.0 228 7/3/2026
1.1.0 567 7/3/2026
1.0.9 645 7/2/2026

Breaking release: event bindings carry canonical FlowMessage envelopes; ApplicationRuntime.Activity replaces the legacy Events stream. Rebuild consumers and component registrations against this major version.