From 62a35fefc31ef2e9f37143deb3826cc1c14dd0cf Mon Sep 17 00:00:00 2001 From: JerrettDavis Date: Mon, 1 Jun 2026 22:05:09 -0500 Subject: [PATCH] refactor: reuse PatternKit behavior chains --- .../Core/BehaviorPipeline.cs | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/QuickApiMapper.Application/Core/BehaviorPipeline.cs b/src/QuickApiMapper.Application/Core/BehaviorPipeline.cs index 4252d7f..01b6b68 100644 --- a/src/QuickApiMapper.Application/Core/BehaviorPipeline.cs +++ b/src/QuickApiMapper.Application/Core/BehaviorPipeline.cs @@ -15,6 +15,15 @@ public sealed class BehaviorPipeline( ILogger logger ) { + private readonly AsyncActionChain _preRunChain = + BuildPreRunChain(preRunBehaviors.OrderBy(b => b.Order).ToArray(), logger); + + private readonly AsyncActionChain _postRunChain = + BuildPostRunChain(postRunBehaviors.OrderBy(b => b.Order).ToArray(), logger); + + private readonly AsyncActionChain _wholeRunChain = + BuildWholeRunChain(wholeRunBehaviors.OrderBy(b => b.Order).ToArray(), logger); + /// /// Executes the complete behavior pipeline around the core mapping logic. /// @@ -66,9 +75,33 @@ private async Task ExecuteWholeRunBehaviors( Func> coreLogic) { var state = new BehaviorExecutionState(context, coreLogic); + + await _wholeRunChain.ExecuteAsync(state, context.CancellationToken).ConfigureAwait(false); + + return state.Result ?? CreateMissingResultFailure(); + } + + private async Task ExecutePreRunBehaviors(MappingContext context) + { + await _preRunChain.ExecuteAsync(context, context.CancellationToken).ConfigureAwait(false); + } + + private async Task ExecutePostRunBehaviors( + MappingContext context, + ContractsMappingResult result) + { + var state = new PostRunBehaviorExecutionState(context, result); + + await _postRunChain.ExecuteAsync(state, context.CancellationToken).ConfigureAwait(false); + } + + private static AsyncActionChain BuildWholeRunChain( + IReadOnlyList behaviors, + ILogger logger) + { var builder = AsyncActionChain.Create(); - foreach (var behavior in wholeRunBehaviors.OrderBy(b => b.Order)) + foreach (var behavior in behaviors) { builder.Use(async (current, ct, next) => { @@ -98,16 +131,16 @@ async Task ContinueAsync(MappingContext nextContext) current.Result = await current.CoreLogic(current.Context).ConfigureAwait(false); }); - await builder.Build().ExecuteAsync(state, context.CancellationToken).ConfigureAwait(false); - - return state.Result ?? CreateMissingResultFailure(); + return builder.Build(); } - private async Task ExecutePreRunBehaviors(MappingContext context) + private static AsyncActionChain BuildPreRunChain( + IReadOnlyList behaviors, + ILogger logger) { var builder = AsyncActionChain.Create(); - foreach (var behavior in preRunBehaviors.OrderBy(b => b.Order)) + foreach (var behavior in behaviors) { builder.Use(async (current, ct, next) => { @@ -128,17 +161,16 @@ private async Task ExecutePreRunBehaviors(MappingContext context) }); } - await builder.Build().ExecuteAsync(context, context.CancellationToken).ConfigureAwait(false); + return builder.Build(); } - private async Task ExecutePostRunBehaviors( - MappingContext context, - ContractsMappingResult result) + private static AsyncActionChain BuildPostRunChain( + IReadOnlyList behaviors, + ILogger logger) { - var state = new PostRunBehaviorExecutionState(context, result); var builder = AsyncActionChain.Create(); - foreach (var behavior in postRunBehaviors.OrderBy(b => b.Order)) + foreach (var behavior in behaviors) { builder.Use(async (current, ct, next) => { @@ -158,7 +190,7 @@ private async Task ExecutePostRunBehaviors( }); } - await builder.Build().ExecuteAsync(state, context.CancellationToken).ConfigureAwait(false); + return builder.Build(); } private static ContractsMappingResult CreateMissingResultFailure()