diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc2146b9..3c25c7fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,10 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: '6.0.x' + - name: Setup dotnet 8.0 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '8.0.100-rc.2.23502.2' - name: Build and Test run: ./Build.ps1 shell: pwsh diff --git a/samples/MediatR.Examples.AspNetCore/MediatR.Examples.AspNetCore.csproj b/samples/MediatR.Examples.AspNetCore/MediatR.Examples.AspNetCore.csproj index 201f9a3a..c257e315 100644 --- a/samples/MediatR.Examples.AspNetCore/MediatR.Examples.AspNetCore.csproj +++ b/samples/MediatR.Examples.AspNetCore/MediatR.Examples.AspNetCore.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Exe @@ -10,7 +10,7 @@ - + diff --git a/samples/MediatR.Examples.Autofac/MediatR.Examples.Autofac.csproj b/samples/MediatR.Examples.Autofac/MediatR.Examples.Autofac.csproj index 6dc8561a..f9f44666 100644 --- a/samples/MediatR.Examples.Autofac/MediatR.Examples.Autofac.csproj +++ b/samples/MediatR.Examples.Autofac/MediatR.Examples.Autofac.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Exe @@ -10,9 +10,9 @@ - + - + diff --git a/samples/MediatR.Examples.DryIoc/MediatR.Examples.DryIoc.csproj b/samples/MediatR.Examples.DryIoc/MediatR.Examples.DryIoc.csproj index 7c234d30..cd9a913a 100644 --- a/samples/MediatR.Examples.DryIoc/MediatR.Examples.DryIoc.csproj +++ b/samples/MediatR.Examples.DryIoc/MediatR.Examples.DryIoc.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Exe @@ -10,8 +10,8 @@ - - + + diff --git a/samples/MediatR.Examples.Lamar/MediatR.Examples.Lamar.csproj b/samples/MediatR.Examples.Lamar/MediatR.Examples.Lamar.csproj index cd1f681b..b312a237 100644 --- a/samples/MediatR.Examples.Lamar/MediatR.Examples.Lamar.csproj +++ b/samples/MediatR.Examples.Lamar/MediatR.Examples.Lamar.csproj @@ -2,12 +2,13 @@ Exe - net6.0 + net8.0 - - + + + diff --git a/samples/MediatR.Examples.LightInject/MediatR.Examples.LightInject.csproj b/samples/MediatR.Examples.LightInject/MediatR.Examples.LightInject.csproj index 5169872c..b6a051d4 100644 --- a/samples/MediatR.Examples.LightInject/MediatR.Examples.LightInject.csproj +++ b/samples/MediatR.Examples.LightInject/MediatR.Examples.LightInject.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 Exe @@ -10,9 +10,9 @@ - - - + + + diff --git a/samples/MediatR.Examples.PublishStrategies/MediatR.Examples.PublishStrategies.csproj b/samples/MediatR.Examples.PublishStrategies/MediatR.Examples.PublishStrategies.csproj index 5511431c..4e3cf954 100644 --- a/samples/MediatR.Examples.PublishStrategies/MediatR.Examples.PublishStrategies.csproj +++ b/samples/MediatR.Examples.PublishStrategies/MediatR.Examples.PublishStrategies.csproj @@ -2,11 +2,11 @@ Exe - net6.0 + net8.0 - + diff --git a/samples/MediatR.Examples.SimpleInjector/MediatR.Examples.SimpleInjector.csproj b/samples/MediatR.Examples.SimpleInjector/MediatR.Examples.SimpleInjector.csproj index d5bc5856..a9f2a713 100644 --- a/samples/MediatR.Examples.SimpleInjector/MediatR.Examples.SimpleInjector.csproj +++ b/samples/MediatR.Examples.SimpleInjector/MediatR.Examples.SimpleInjector.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 Exe @@ -10,9 +10,9 @@ - - - + + + diff --git a/samples/MediatR.Examples.Stashbox/MediatR.Examples.Stashbox.csproj b/samples/MediatR.Examples.Stashbox/MediatR.Examples.Stashbox.csproj index bc2d1194..5c9a569f 100644 --- a/samples/MediatR.Examples.Stashbox/MediatR.Examples.Stashbox.csproj +++ b/samples/MediatR.Examples.Stashbox/MediatR.Examples.Stashbox.csproj @@ -2,12 +2,12 @@ Exe - net6.0 + net8.0 - - + + diff --git a/src/MediatR.Contracts/MediatR.Contracts.csproj b/src/MediatR.Contracts/MediatR.Contracts.csproj index c15f9c30..a311f618 100644 --- a/src/MediatR.Contracts/MediatR.Contracts.csproj +++ b/src/MediatR.Contracts/MediatR.Contracts.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/MediatR/MediatR.csproj b/src/MediatR/MediatR.csproj index 37a40fd6..44270629 100644 --- a/src/MediatR/MediatR.csproj +++ b/src/MediatR/MediatR.csproj @@ -32,9 +32,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/src/MediatR/Registration/ServiceRegistrar.cs b/src/MediatR/Registration/ServiceRegistrar.cs index 0d69e158..721312eb 100644 --- a/src/MediatR/Registration/ServiceRegistrar.cs +++ b/src/MediatR/Registration/ServiceRegistrar.cs @@ -258,6 +258,7 @@ public static void AddRequiredServices(IServiceCollection services, MediatRServi private static void RegisterBehaviorIfImplementationsExist(IServiceCollection services, Type behaviorType, Type subBehaviorType) { var hasAnyRegistrationsOfSubBehaviorType = services + .Where(service => !service.IsKeyedService) .Select(service => service.ImplementationType) .OfType() .SelectMany(type => type.GetInterfaces()) diff --git a/test/MediatR.Benchmarks/MediatR.Benchmarks.csproj b/test/MediatR.Benchmarks/MediatR.Benchmarks.csproj index 1946994d..1d88a19c 100644 --- a/test/MediatR.Benchmarks/MediatR.Benchmarks.csproj +++ b/test/MediatR.Benchmarks/MediatR.Benchmarks.csproj @@ -12,9 +12,9 @@ Release - - - + + + diff --git a/test/MediatR.Tests/MediatR.Tests.csproj b/test/MediatR.Tests/MediatR.Tests.csproj index a4330339..cff87cca 100644 --- a/test/MediatR.Tests/MediatR.Tests.csproj +++ b/test/MediatR.Tests/MediatR.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable @@ -10,13 +10,14 @@ - - - - + + + + - - + + + all runtime; build; native; contentfiles; analyzers diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs index 83ed7998..f5175b91 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs @@ -41,7 +41,7 @@ public void ShouldResolveInternalHandler() [Fact] public void ShouldResolveNotificationHandlers() { - _provider.GetServices>().Count().ShouldBe(3); + _provider.GetServices>().Count().ShouldBe(4); } [Fact] diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/CustomMediatorTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/CustomMediatorTests.cs index c4ce133c..65eb3276 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/CustomMediatorTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/CustomMediatorTests.cs @@ -39,7 +39,7 @@ public void ShouldResolveRequestHandler() [Fact] public void ShouldResolveNotificationHandlers() { - _provider.GetServices>().Count().ShouldBe(3); + _provider.GetServices>().Count().ShouldBe(4); } [Fact] diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/DuplicateAssemblyResolutionTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/DuplicateAssemblyResolutionTests.cs index 7524c475..819b8f5d 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/DuplicateAssemblyResolutionTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/DuplicateAssemblyResolutionTests.cs @@ -22,6 +22,6 @@ public DuplicateAssemblyResolutionTests() [Fact] public void ShouldResolveNotificationHandlersOnlyOnce() { - _provider.GetServices>().Count().ShouldBe(3); + _provider.GetServices>().Count().ShouldBe(4); } } \ No newline at end of file diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/Handlers.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/Handlers.cs index 62768991..f71c407e 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/Handlers.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/Handlers.cs @@ -78,6 +78,12 @@ public Task Handle(Pinged notification, CancellationToken cancellationToken) } } + public class PingedAlsoOpenHandler : INotificationHandler + where TNotification : Pinged + { + public Task Handle(TNotification notification, CancellationToken cancellationToken) => Task.CompletedTask; + } + public class Logger { public IList Messages { get; } = new List(); diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/PipelineTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/PipelineTests.cs index 1d231e83..3722a378 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/PipelineTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/PipelineTests.cs @@ -1,5 +1,7 @@ using System.Runtime.CompilerServices; using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; +using Xunit.Abstractions; namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests; @@ -843,4 +845,98 @@ public void Should_handle_open_behaviors_registration_from_a_single_type() services.BuildServiceProvider(); }); } + + public sealed record FooRequest : IRequest; + + public interface IBlogger + { + IList Messages { get; } + } + + public class Blogger : IBlogger + { + private readonly Logger _logger; + + public Blogger(Logger logger) + { + _logger = logger; + } + + public IList Messages => _logger.Messages; + } + + public sealed class FooRequestHandler : IRequestHandler { + public FooRequestHandler(IBlogger logger) + { + this.logger = logger; + } + + readonly IBlogger logger; + + public Task Handle(FooRequest request, CancellationToken cancellationToken) { + logger.Messages.Add("Invoked Handler"); + return Task.CompletedTask; + } + } + + sealed class ClosedBehavior : IPipelineBehavior { + public ClosedBehavior(IBlogger logger) + { + this.logger = logger; + } + + readonly IBlogger logger; + + public Task Handle(FooRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { + logger.Messages.Add("Invoked Closed Behavior"); + return next(); + } + } + + sealed class Open2Behavior : IPipelineBehavior + where TRequest : notnull { + public Open2Behavior(IBlogger> logger) { + this.logger = logger; + } + + readonly IBlogger> logger; + + public Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { + logger.Messages.Add("Invoked Open Behavior"); + return next(); + } + } + [Fact] + public async Task Should_register_correctly() + { + var services = new ServiceCollection(); + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssemblyContaining(); + cfg.AddBehavior(); + cfg.AddOpenBehavior(typeof(Open2Behavior<,>)); + }); + var logger = new Logger(); + services.AddSingleton(logger); + services.AddSingleton(new MediatR.Tests.PipelineTests.Logger()); + services.AddSingleton(new MediatR.Tests.StreamPipelineTests.Logger()); + services.AddSingleton(new MediatR.Tests.SendTests.Dependency()); + services.AddSingleton(new System.IO.StringWriter()); + services.AddTransient(typeof(IBlogger<>), typeof(Blogger<>)); + var provider = services.BuildServiceProvider(new ServiceProviderOptions + { + ValidateOnBuild = true + }); + + var mediator = provider.GetRequiredService(); + var request = new FooRequest(); + await mediator.Send(request); + + logger.Messages.ShouldBe(new [] + { + "Invoked Closed Behavior", + "Invoked Open Behavior", + "Invoked Handler", + }); + } } \ No newline at end of file diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/TypeResolutionTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/TypeResolutionTests.cs index 324fa519..4438cafd 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/TypeResolutionTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/TypeResolutionTests.cs @@ -55,7 +55,7 @@ public void ShouldResolveVoidRequestHandler() [Fact] public void ShouldResolveNotificationHandlers() { - _provider.GetServices>().Count().ShouldBe(3); + _provider.GetServices>().Count().ShouldBe(4); } [Fact] @@ -77,4 +77,18 @@ public void ShouldResolveIgnoreSecondDuplicateHandler() { _provider.GetServices>().Count().ShouldBe(1); } + + [Fact] + public void ShouldHandleKeyedServices() + { + IServiceCollection services = new ServiceCollection(); + services.AddSingleton(new Logger()); + services.AddKeyedSingleton("Foo", "Foo"); + services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining(typeof(Ping))); + var serviceProvider = services.BuildServiceProvider(); + + var mediator = serviceProvider.GetRequiredService(); + + mediator.ShouldNotBeNull(); + } } \ No newline at end of file