Strongflow.Generators
0.0.1-beta.25
dotnet add package Strongflow.Generators --version 0.0.1-beta.25
NuGet\Install-Package Strongflow.Generators -Version 0.0.1-beta.25
<PackageReference Include="Strongflow.Generators" Version="0.0.1-beta.25"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Strongflow.Generators" Version="0.0.1-beta.25" />
<PackageReference Include="Strongflow.Generators"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Strongflow.Generators --version 0.0.1-beta.25
#r "nuget: Strongflow.Generators, 0.0.1-beta.25"
#:package Strongflow.Generators@0.0.1-beta.25
#addin nuget:?package=Strongflow.Generators&version=0.0.1-beta.25&prerelease
#tool nuget:?package=Strongflow.Generators&version=0.0.1-beta.25&prerelease
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.
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/awaitandValueTask - 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 withIntercept()andInterceptAsync()methodsCalle<TFn, TArgs, TResult>: Call descriptor for synchronous calls - provides method metadata, arguments, chains viaNext()CalleAsync<TFn, TArgs, TResult>: Call descriptor for async calls - chains viaNextAsync()DecoratedProcessor: Main execution engine withProcess()andProcessAsync()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.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Strongflow.Generators:
| Package | Downloads |
|---|---|
|
Strongflow
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-beta.25 | 65 | 4/22/2026 |
| 0.0.1-beta.24 | 54 | 4/20/2026 |
| 0.0.1-beta.23 | 60 | 4/20/2026 |
| 0.0.1-beta.22 | 60 | 4/20/2026 |
| 0.0.1-beta.21 | 57 | 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 | 63 | 4/17/2026 |
| 0.0.1-beta.17 | 73 | 4/17/2026 |
| 0.0.1-beta.16 | 61 | 4/17/2026 |
| 0.0.1-beta.15 | 60 | 4/15/2026 |
| 0.0.1-beta.14 | 166 | 4/7/2026 |
| 0.0.1-beta.13 | 356 | 4/5/2026 |
| 0.0.1-beta.12 | 66 | 4/5/2026 |
| 0.0.1-beta.11 | 57 | 4/5/2026 |
| 0.0.1-beta.10 | 57 | 4/5/2026 |
| 0.0.1-beta.9 | 65 | 4/4/2026 |
| 0.0.1-beta.8 | 65 | 4/4/2026 |
| 0.0.1-beta.7 | 84 | 4/4/2026 |
| 0.0.1-beta.6 | 63 | 4/4/2026 |