SkyHigh.StaticProxy
8.0.1
See the version list below for details.
dotnet add package SkyHigh.StaticProxy --version 8.0.1
NuGet\Install-Package SkyHigh.StaticProxy -Version 8.0.1
<PackageReference Include="SkyHigh.StaticProxy" Version="8.0.1" />
<PackageVersion Include="SkyHigh.StaticProxy" Version="8.0.1" />
<PackageReference Include="SkyHigh.StaticProxy" />
paket add SkyHigh.StaticProxy --version 8.0.1
#r "nuget: SkyHigh.StaticProxy, 8.0.1"
#:package SkyHigh.StaticProxy@8.0.1
#addin nuget:?package=SkyHigh.StaticProxy&version=8.0.1
#tool nuget:?package=SkyHigh.StaticProxy&version=8.0.1
SkyHigh.StaticProxy
SkyHigh.StaticProxy is a lightweight, high-performance .NET library that provides compile-time method interception through source generators. It allows you to implement Aspect-Oriented Programming (AOP) patterns without the runtime overhead of traditional dynamic proxies.
Features
- Compile-Time Proxy Generation: Generate proxy classes at compile time using C# Source Generators
- High Performance: No runtime reflection overhead compared to dynamic proxies
- Aspect-Oriented Programming: Cleanly separate cross-cutting concerns such as logging, caching, and performance monitoring
- DI Integration: Seamless integration with Microsoft's Dependency Injection system
- Multiple Interceptors: Apply multiple interceptors to a single service
- Async Support: Full support for async methods with Task and ValueTask return types
- Minimal Dependencies: Only requires Microsoft.Extensions.DependencyInjection.Abstractions
- Multi-Target: Supports .NET Standard 2.0 and .NET 9.0
Installation
Install the package via NuGet Package Manager:
dotnet add package SkyHigh.StaticProxy
Quick Start
1. Define Your Interface and Implementation
public interface IMyService
{
string GetData(string key);
Task<int> GetCountAsync();
}
public class MyService : IMyService
{
public string GetData(string key)
{
return $"Data for {key}";
}
public async Task<int> GetCountAsync()
{
await Task.Delay(100); // Simulate work
return 42;
}
}
2. Create an Interceptor
public class LoggingInterceptor<TInterface, TImplementation> : IInterceptor<TInterface, TImplementation>
where TImplementation : class, TInterface
{
private readonly ILogger _logger;
public LoggingInterceptor(ILogger<LoggingInterceptor<TInterface, TImplementation>> logger)
{
_logger = logger;
}
public void Intercept(IInterceptorContext<TInterface, TImplementation> context)
{
_logger.LogInformation($"Calling {context.InterfaceMethodInfo.Name}");
context.Proceed();
_logger.LogInformation($"Completed {context.InterfaceMethodInfo.Name}");
}
public async Task InterceptAsync(IInterceptorContext<TInterface, TImplementation> context)
{
_logger.LogInformation($"Calling async {context.InterfaceMethodInfo.Name}");
await context.ProceedAsync();
_logger.LogInformation($"Completed async {context.InterfaceMethodInfo.Name}");
}
}
3. Register Services with Interceptors
var builder = WebApplication.CreateBuilder(args);
// Register service with interceptor
builder.Services.AddScopedWithInterceptors<IMyService, MyService>(typeof(LoggingInterceptor<,>));
// Multiple interceptors can be applied
builder.Services.AddSingletonWithInterceptors<IOtherService, OtherService>(
typeof(LoggingInterceptor<,>),
typeof(PerformanceInterceptor<,>));
How It Works
SkyHigh.StaticProxy uses C# Source Generators to analyze your code at compile time. When you register a service with interceptors, the SkyHigh.StaticProxy.Generator creates a strongly-typed proxy class that:
- Implements the target interface
- Wraps the actual implementation
- Applies interceptors to each method call
- Handles both synchronous and asynchronous methods
This approach provides the benefits of AOP without the performance penalties of runtime reflection or dynamic proxy generation.
Interceptor Context
The IInterceptorContext<TInterface, TImplementation>
provides key information and control:
InterfaceMethodInfo
: Information about the intercepted methodImplementationMethodInfo
: Information about the implementation methodParameters
: The parameters passed to the methodReturnValue
: The return value (available after Proceed/ProceedAsync)Implementation
: The actual implementation instanceProceed()
: Calls the next interceptor or the implementation methodProceedAsync()
: Async version of Proceed()
Advanced Usage
Creating a Performance Monitoring Interceptor
public class PerformanceInterceptor<TInterface, TImplementation> : IInterceptor<TInterface, TImplementation>
where TImplementation : class, TInterface
{
private readonly ILogger _logger;
public PerformanceInterceptor(ILogger<PerformanceInterceptor<TInterface, TImplementation>> logger)
{
_logger = logger;
}
public void Intercept(IInterceptorContext<TInterface, TImplementation> context)
{
var stopwatch = Stopwatch.StartNew();
try
{
context.Proceed();
}
finally
{
stopwatch.Stop();
_logger.LogInformation($"{context.InterfaceMethodInfo.Name} executed in {stopwatch.ElapsedMilliseconds}ms");
}
}
public async Task InterceptAsync(IInterceptorContext<TInterface, TImplementation> context)
{
var stopwatch = Stopwatch.StartNew();
try
{
await context.ProceedAsync();
}
finally
{
stopwatch.Stop();
_logger.LogInformation($"{context.InterfaceMethodInfo.Name} executed in {stopwatch.ElapsedMilliseconds}ms");
}
}
}
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Product | Versions 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 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 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 | 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. |
-
.NETStandard 2.0
-
net8.0
-
net9.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.