diff --git a/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs b/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs index c4ef7668..e42ac0b9 100644 --- a/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs +++ b/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs @@ -47,6 +47,11 @@ public class MediatRServiceConfiguration /// public List BehaviorsToRegister { get; } = new(); + /// + /// List of stream behaviors to register in specific order + /// + public List StreamBehaviorsToRegister { get; } = new(); + /// /// Register various handlers from assembly containing given type /// @@ -140,4 +145,28 @@ public MediatRServiceConfiguration AddOpenBehavior(Type openBehaviorType, Servic return this; } + + /// + /// Register a closed stream behavior type + /// + /// Closed stream behavior interface type + /// Closed stream behavior implementation type + /// Optional service lifetime, defaults to . + /// This + public MediatRServiceConfiguration AddStreamBehavior(ServiceLifetime serviceLifetime = ServiceLifetime.Transient) + => AddStreamBehavior(typeof(TServiceType), typeof(TImplementationType), serviceLifetime); + + /// + /// Register a closed stream behavior type + /// + /// Closed stream behavior interface type + /// Closed stream behavior implementation type + /// Optional service lifetime, defaults to . + /// This + public MediatRServiceConfiguration AddStreamBehavior(Type serviceType, Type implementationType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient) + { + StreamBehaviorsToRegister.Add(new ServiceDescriptor(serviceType, implementationType, serviceLifetime)); + + return this; + } } \ No newline at end of file diff --git a/src/MediatR/Registration/ServiceRegistrar.cs b/src/MediatR/Registration/ServiceRegistrar.cs index c514c50f..39ffab57 100644 --- a/src/MediatR/Registration/ServiceRegistrar.cs +++ b/src/MediatR/Registration/ServiceRegistrar.cs @@ -225,6 +225,11 @@ public static void AddRequiredServices(IServiceCollection services, MediatRServi services.TryAdd(notificationPublisherServiceDescriptor); foreach (var serviceDescriptor in serviceConfiguration.BehaviorsToRegister) + { + services.TryAddEnumerable(serviceDescriptor); + } + + foreach (var serviceDescriptor in serviceConfiguration.StreamBehaviorsToRegister) { services.TryAddEnumerable(serviceDescriptor); } diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/StreamPipelineTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/StreamPipelineTests.cs index 01dd4572..df801db7 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/StreamPipelineTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/StreamPipelineTests.cs @@ -84,4 +84,38 @@ public async Task Should_wrap_with_behavior() "Outer after" }); } + + [Fact] + public async Task Should_register_and_wrap_with_behavior() + { + var output = new Logger(); + IServiceCollection services = new ServiceCollection(); + services.AddSingleton(output); + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssembly(typeof(Ping).Assembly); + cfg.AddStreamBehavior, OuterBehavior>(); + cfg.AddStreamBehavior, InnerBehavior>(); + }); + var provider = services.BuildServiceProvider(); + + var mediator = provider.GetRequiredService(); + + var stream = mediator.CreateStream(new StreamPing { Message = "Ping" }); + + await foreach (var response in stream) + { + response.Message.ShouldBe("Ping Pang"); + } + + output.Messages.ShouldBe(new[] + { + "Outer before", + "Inner before", + "Handler", + "Inner after", + "Outer after" + }); + } + } \ No newline at end of file