Strongflow 0.0.1-beta.25

This is a prerelease version of Strongflow.
dotnet add package Strongflow --version 0.0.1-beta.25
                    
NuGet\Install-Package Strongflow -Version 0.0.1-beta.25
                    
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="Strongflow" Version="0.0.1-beta.25" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Strongflow" Version="0.0.1-beta.25" />
                    
Directory.Packages.props
<PackageReference Include="Strongflow" />
                    
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 Strongflow --version 0.0.1-beta.25
                    
#r "nuget: Strongflow, 0.0.1-beta.25"
                    
#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 Strongflow@0.0.1-beta.25
                    
#: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=Strongflow&version=0.0.1-beta.25&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Strongflow&version=0.0.1-beta.25&prerelease
                    
Install as a Cake Tool

Strongflow

A .NET library that uses C# Source Generators to automatically generate strongly-typed decorators and interceptors with compile-time safety and zero runtime overhead.

Build Status License: MIT NuGet

Overview

Strongflow lets you apply cross-cutting concerns (logging, caching, performance monitoring, authentication) to your methods using declarative attributes. Decorators are generated at compile-time via source generators, ensuring maximum performance with no reflection overhead.

Key Features

  • Compile-Time Generation: All decorators generated via C# Source Generators
  • Type-Safe: Full generic type support with compile-time checking
  • Zero Runtime Overhead: No reflection, no dynamic proxies
  • Async Support: First-class support for async/await and ValueTask
  • Interceptor Chains: Chain multiple interceptors for sequential execution
  • DI Integration: Built-in support for Microsoft.Extensions.DependencyInjection and Autofac

Installation

dotnet add package Strongflow.Abstractions
dotnet add package Strongflow.Generators

Quick Start

1. Define an Interceptor

using Strongflow.Abstractions;

public class LoggingInterceptor : IInterceptor
{
    public TResult Intercept<TFn, TArgs, TResult>(Calle<TFn, TArgs, TResult> call) where TFn : Delegate
    {
        var methodName = call.MethodInvocationTarget?.Name ?? "Unknown";
        Console.WriteLine($"Executing {methodName}");

        var result = call.Next();

        Console.WriteLine($"Completed {methodName}");
        return result;
    }

    public async ValueTask<TResult> InterceptAsync<TFn, TArgs, TResult>(
        CalleAsync<TFn, TArgs, TResult> call,
        CancellationToken cancellationToken = default)
    {
        var methodName = call.MethodInvocationTarget?.Name ?? "Unknown";
        Console.WriteLine($"Executing {methodName}");

        var result = await call.NextAsync();

        Console.WriteLine($"Completed {methodName}");
        return result;
    }
}

2. Use the Decorator

public class UserService
{
    private readonly IInterceptor _interceptor = new LoggingInterceptor();

    public int GetUserCount()
    {
        return DecoratedProcessor.Process(_interceptor, () =>
        {
            // Your business logic
            return 42;
        });
    }

    public async Task<string> GetUserNameAsync(int userId)
    {
        return await DecoratedProcessor.ProcessAsync(
            _interceptor,
            async () =>
            {
                await Task.Delay(100);
                return $"User {userId}";
            },
            CancellationToken.None);
    }
}

3. Chain Multiple Interceptors

public class CombinedInterceptor : IInterceptorForward
{
    private readonly IInterceptorForward? _next;

    public CombinedInterceptor(IInterceptorForward? next = null) => _next = next;

    public TResult Intercept<TFn, TArgs, TResult>(Calle<TFn, TArgs, TResult> call) where TFn : Delegate
    {
        Console.WriteLine("Before execution");
        var result = call.Next();
        Console.WriteLine("After execution");
        return result;
    }

    public ValueTask<TResult> InterceptAsync<TFn, TArgs, TResult>(
        CalleAsync<TFn, TArgs, TResult> call,
        CancellationToken cancellationToken = default)
    {
        return call.NextAsync();
    }

    public IInterceptorForward? ForwardΔ() => _next;
}

Dependency Injection

Microsoft.Extensions.DependencyInjection

using Microsoft.Extensions.DependencyInjection;
using Strongflow.Abstractions.MicrosoftDI;

var services = new ServiceCollection();

// Register a single interceptor (transient)
services.AddInterceptor<LoggingInterceptor>();

// Register with custom lifetime
services.AddInterceptor<CachingInterceptor>(ServiceLifetime.Singleton);

// Register with factory
services.AddInterceptor<CustomInterceptor>(
    sp => new CustomInterceptor(sp.GetRequiredService<ILogger>()),
    ServiceLifetime.Scoped);

var serviceProvider = services.BuildServiceProvider();

// Get interceptor from DI
var interceptor = serviceProvider.GetRequiredService<IInterceptor>();

// Or use the helper class
var interceptorProvider = new InterceptorServiceProvider(serviceProvider);
var result = interceptorProvider.Process(() => GetData());

Autofac

using Strongflow.Autofac;

var module = Strong.BuildModule("MyModule")
    .RegisterAssemblyTypes()
    .AsImplementedInterfaces()
    .EnableClassInterceptors()
    .InterceptedBy(typeof(LoggingInterceptor));

var builder = new ContainerBuilder();
builder.RegisterModule(module);
var container = builder.Build();

Project Structure

Strongflow.sln
├── Strongflow.Abstractions/          # Core interfaces (IInterceptor, Calle, CalleAsync)
├── Strongflow.Generator/             # Source generator implementation
├── Strongflow.Generators.Tests/      # Unit tests (200+)
├── Strongflow.Autofac/               # Autofac integration
├── Strongflow.Autofac.Tests/         # Autofac-specific tests
├── Strongflow.Benchmark/             # Performance benchmarks
└── Strongflow.Examples/              # Usage examples

Architecture

Core Components

  • IInterceptor: Base interface for all interceptors with Intercept() and InterceptAsync() methods
  • Calle<TFn, TArgs, TResult>: Call descriptor for synchronous calls - provides method metadata, arguments, chains via Next()
  • CalleAsync<TFn, TArgs, TResult>: Call descriptor for async calls - chains via NextAsync()
  • DecoratedProcessor: Main execution engine with Process() and ProcessAsync() methods

Interceptor Chain Pattern

Method Call → Interceptor 1 (Pre) → Interceptor 2 (Pre) → Actual Method → Interceptor 2 (Post) → Interceptor 1 (Post) → Result

Performance

Strongflow generates decorators at compile-time, resulting in:

  • Zero reflection at runtime
  • No dynamic proxies
  • Direct IL code generation
  • Inlining-friendly code that optimizes well with the JIT

Run benchmarks with:

dotnet run --project Strongflow.Benchmark/Strongflow.Benchmark.csproj --configuration Release

Testing

dotnet test

License

MIT License - see LICENSE file for details.

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 is compatible.  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 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen 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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.1-beta.25 64 4/22/2026
0.0.1-beta.24 53 4/20/2026
0.0.1-beta.23 65 4/20/2026
0.0.1-beta.22 64 4/20/2026
0.0.1-beta.21 55 4/20/2026
0.0.1-beta.20 58 4/18/2026
0.0.1-beta.19 56 4/17/2026
0.0.1-beta.18 57 4/17/2026
0.0.1-beta.17 73 4/17/2026
0.0.1-beta.16 63 4/17/2026
0.0.1-beta.15 60 4/15/2026
0.0.1-beta.14 167 4/7/2026
0.0.1-beta.13 356 4/5/2026
0.0.1-beta.12 65 4/5/2026
0.0.1-beta.11 57 4/5/2026
0.0.1-beta.10 59 4/5/2026
0.0.1-beta.9 74 4/4/2026
0.0.1-beta.8 60 4/4/2026
0.0.1-beta.7 83 4/4/2026
0.0.1-beta.6 59 4/4/2026
Loading failed