Skip to content

Instantly share code, notes, and snippets.

View AnthonyGiretti's full-sized avatar
💭
👍

[MVP] Anthony Giretti AnthonyGiretti

💭
👍
View GitHub Profile
@AnthonyGiretti
AnthonyGiretti / AuditMiddleware.cs
Created April 3, 2026 14:45
ASP.NET Core 10: Clearer Separation Between Middlewares and Endpoints for More Predictable Routing (custom middleware)
public class AuditMiddleware
{
private readonly RequestDelegate _next;
public AuditMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var endpoint = context.GetEndpoint(); // <-- Enables benefit of the middleware improvement
var requiresAudit = endpoint?.Metadata.GetMetadata<RequiresAuditAttribute>();
@AnthonyGiretti
AnthonyGiretti / Program.cs
Created March 22, 2026 02:35
Introduction to C# 14 Interceptors
// This attribute encodes the exact position of the call site to intercept:
// file path + line + column, hashed into a compact base64 string
[InterceptsLocationAttribute(1, "qjmcoI/hUdYHdlM5/alrVYsBAABPcmRlclNlcnZpY2UuY3M=")]
internal static void Log_Intercepted_0(string message, LogLevel level)
{
// Substitute logic — zero-allocation, AOT-friendly, audit trail, etc.
StructuredLogger.Write(level, message);
}
@AnthonyGiretti
AnthonyGiretti / Program.cs
Created March 22, 2026 02:34
Introduction to C# 14 Interceptors
// This is what ends up in the compiled IL — invisible to the developer
GeneratedInterceptors.Log_Intercepted_0("Order created", LogLevel.Information);
@AnthonyGiretti
AnthonyGiretti / Program.cs
Created March 22, 2026 02:34
Introduction to C# 14 Interceptors
// This is what the developer writes
Logger.Log("Order created", LogLevel.Information);
@AnthonyGiretti
AnthonyGiretti / HttpClientInterceptors.g.cs
Created March 22, 2026 01:14
C# 14 Interceptors - Generate HttpClientInterceptors injected in-memory by Roslyn
// <auto-generated/>
#nullable enable
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using MyApi;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
@AnthonyGiretti
AnthonyGiretti / Generate.cs
Created March 22, 2026 01:11
C# 14 Interceptors - Generate method, inside HttpClientInterceptorGenerator.cs
private static void Generate(
SourceProductionContext spc,
ImmutableArray<InterceptorTarget> targets)
{
if (targets.IsDefaultOrEmpty) return;
var sb = new StringBuilder();
sb.AppendLine("// <auto-generated/>");
sb.AppendLine("#nullable enable");
sb.AppendLine("using System.Net.Http;");
@AnthonyGiretti
AnthonyGiretti / HttpClientInterceptorGenerator.cs
Last active March 22, 2026 01:12
C# 14 Interceptors - The HttpClient Interceptor Generator
using System.Collections.Immutable;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace CorrelationInterceptors.Generator;
[Generator]
public sealed class HttpClientInterceptorGenerator : IIncrementalGenerator
@AnthonyGiretti
AnthonyGiretti / OrderService.cs
Created March 22, 2026 01:00
C# 14 Interceptors - OrderService that performs Http calls via HttpClient
namespace MyApi;
public class OrderService(HttpClient httpClient)
{
public async Task<string> GetOrderAsync(Guid orderId)
{
var request = new HttpRequestMessage(
HttpMethod.Get, $"https://orders-api/orders/{orderId}");
// No manual header injection — the interceptor handles it at compile time
@AnthonyGiretti
AnthonyGiretti / CorrelationMiddleware.cs
Created March 22, 2026 00:59
C# 14 Interceptors - CorrelationMiddleware that sets the ambient value per request
namespace MyApi;
public class CorrelationMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext context)
{
CorrelationContext.CorrelationId =
context.Request.Headers["X-Correlation-ID"].FirstOrDefault()
?? Guid.NewGuid().ToString();
@AnthonyGiretti
AnthonyGiretti / CorrelationContext.cs
Created March 22, 2026 00:58
C# 14 Interceptors - CorrelationContext that carries the Correlation Id
namespace MyApi;
public static class CorrelationContext
{
private static readonly AsyncLocal<string?> _correlationId = new();
public static string? CorrelationId
{
get => _correlationId.Value;
set => _correlationId.Value = value;