feat(dispatcher): add registration-time pipeline behavior ordering via AddBehavior<T>(order:)
All checks were successful
default / dotnet-default-workflow (push) Successful in 1m58s

Pipeline behavior ordering previously depended on discovery/registration
order. Add an AddBehavior<T>(order:) API that captures the order at
registration time; the BehaviorTypeIndex now orders matching behaviors by
that explicit order (lower runs first), falling back to registration order
for ties. Removed the runtime Order property approach.
This commit is contained in:
Louis Seubert 2026-07-12 19:30:59 +02:00
commit ae2c2679f2
Signed by: louis9902
GPG key ID: 4B9DB28F826553BD
7 changed files with 143 additions and 17 deletions

View file

@ -66,6 +66,26 @@ internal sealed class StreamBehaviourTests
await Assert.That(tracker.Log[1]).IsEquivalentTo("Behaviour2");
}
[Test]
public async Task I_can_order_behaviours_explicitly_by_order_property()
{
var sc = new ServiceCollection();
sc.AddSingleton<StreamTestTracker>();
sc.AddRequestDispatcher(builder => builder
.Add(typeof(StreamTestHandler))
.AddBehavior<OrderedStreamBehaviorA>(2)
.AddBehavior<OrderedStreamBehaviorB>(1));
var provider = sc.BuildServiceProvider();
var dispatcher = provider.GetRequiredService<IRequestDispatcher>();
var tracker = provider.GetRequiredService<StreamTestTracker>();
var request = new StreamTestRequest { Value = "Hello" };
await dispatcher.DispatchAsync(request).ToListAsync();
// Registered A (order 2) then B (order 1) via AddBehavior; explicit order overrides discovery order.
await Assert.That(tracker.Log).IsEquivalentTo(["OrderedB", "OrderedA"]);
}
[Test]
public async Task I_can_work_with_a_generic_wrapper_request_and_the_open_behaviour()
{