From 1e427668663be7eed7f55d73f92271ea05697ec8 Mon Sep 17 00:00:00 2001 From: Dan Soltesz Date: Wed, 19 Nov 2025 17:31:00 -0500 Subject: [PATCH] Add IncludeTypesForGeneration feature Introduce IncludeTypesForGeneration in CompilationAnalyzer to filter request types based on marker interfaces, aiding modular monolith architectures. Add a private field to store marker interfaces and update methods to apply filtering logic. Enhance MediatorOptions with a new property for configuration. Include tests to verify functionality and add documentation for usage. Update launch settings and generated code files accordingly. --- docs/IncludeTypesForGeneration.md | 107 ++ .../Properties/launchSettings.json | 12 + .../Analysis/CompilationAnalyzer.cs | 63 + .../resources/MediatorOptions.sbn-cs | 9 + .../ConfigurationTests.cs | 282 ++++ ...eneration_EmptyList#Mediator.g.verified.cs | 1266 ++++++++++++++++ ...larMonolith_TwoAPIs#Mediator.g.verified.cs | 1300 ++++++++++++++++ ...ation_MultipleTypes#Mediator.g.verified.cs | 1334 +++++++++++++++++ ...neration_SingleType#Mediator.g.verified.cs | 1266 ++++++++++++++++ 9 files changed, 5639 insertions(+) create mode 100644 docs/IncludeTypesForGeneration.md create mode 100644 samples/use-cases/MassTransitIntegration/Properties/launchSettings.json create mode 100644 test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_EmptyList#Mediator.g.verified.cs create mode 100644 test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_ModularMonolith_TwoAPIs#Mediator.g.verified.cs create mode 100644 test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_MultipleTypes#Mediator.g.verified.cs create mode 100644 test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_SingleType#Mediator.g.verified.cs diff --git a/docs/IncludeTypesForGeneration.md b/docs/IncludeTypesForGeneration.md new file mode 100644 index 00000000..58a6a181 --- /dev/null +++ b/docs/IncludeTypesForGeneration.md @@ -0,0 +1,107 @@ +# IncludeTypesForGeneration - Modular Monolith Support + +The `IncludeTypesForGeneration` option enables filtering of request types during source generation based on marker interfaces. This is particularly useful for modular monolith architectures where multiple APIs/modules share the same codebase but should only generate mediator code for their respective requests. + +## How It Works + +When you specify one or more marker interface types in `IncludeTypesForGeneration`, only request types that implement at least one of those marker interfaces will be included in code generation. If the collection is empty or not configured, **all discovered request types will be included** (no filtering applied). + +## Usage Example + +### 1. Define Marker Interfaces + +```csharp +// Marker interface for API1 requests +public interface IApi1Request { } + +// Marker interface for API2 requests +public interface IApi2Request { } +``` + +### 2. Implement Request Types with Marker Interfaces + +```csharp +// Shared between both APIs +public record SharedRequest(Guid Id) + : IRequest, IApi1Request, IApi2Request; + +// API1 only +public record Api1OnlyRequest(Guid Id) + : IRequest, IApi1Request; + +// API2 only +public record Api2OnlyRequest(Guid Id) + : IRequest, IApi2Request; + +// Not included in either API (no marker interface) +public record InternalRequest(Guid Id) + : IRequest; +``` + +### 3. Configure Each API's Mediator + +```csharp +// In Api1's startup/configuration +builder.Services.AddMediator(options => +{ + options.Namespace = "Api1"; + options.ServiceLifetime = ServiceLifetime.Transient; + options.GenerateTypesAsInternal = true; + options.IncludeTypesForGeneration = [typeof(IApi1Request)]; +}); + +// In Api2's startup/configuration +builder.Services.AddMediator(options => +{ + options.Namespace = "Api2"; + options.ServiceLifetime = ServiceLifetime.Transient; + options.GenerateTypesAsInternal = true; + options.IncludeTypesForGeneration = [typeof(IApi2Request)]; +}); +``` + +### Result + +- **Api1** will generate code for: `SharedRequest`, `Api1OnlyRequest` +- **Api2** will generate code for: `SharedRequest`, `Api2OnlyRequest` +- Neither will generate code for: `InternalRequest` (no marker interface) + +## Benefits + +1. **No Service Validation Issues**: Only handlers for included request types are registered in DI, so you won't need to disable validation or deal with missing dependencies for handlers you don't use. + +2. **Clean Separation**: Each API/module only contains mediator code for requests it actually handles. + +3. **Shared Requests**: Requests can be easily shared across multiple APIs by implementing multiple marker interfaces. + +4. **Type Safety**: Compiler ensures requests implement the correct marker interfaces at build time. + +## Aspire Support + +This feature works seamlessly with .NET Aspire applications where you have multiple API projects in the same solution: + +```csharp +// AppHost project +var builder = DistributedApplication.CreateBuilder(args); + +var api1 = builder.AddProject("api1"); +var api2 = builder.AddProject("api2"); +var worker = builder.AddProject("worker"); + +builder.Build().Run(); +``` + +Each project can configure its own mediator with `IncludeTypesForGeneration` to only generate code for its relevant requests. + +## Alternative: Exact Type Filtering + +While the primary use case is marker interfaces, you can also specify exact request types: + +```csharp +options.IncludeTypesForGeneration = [ + typeof(Request1), + typeof(Request2) +]; +``` + +However, this requires listing every request type explicitly and doesn't scale well for modular monoliths. The marker interface approach is recommended. diff --git a/samples/use-cases/MassTransitIntegration/Properties/launchSettings.json b/samples/use-cases/MassTransitIntegration/Properties/launchSettings.json new file mode 100644 index 00000000..5c0d0e70 --- /dev/null +++ b/samples/use-cases/MassTransitIntegration/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "MassTransitIntegration": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:55405;http://localhost:55406" + } + } +} \ No newline at end of file diff --git a/src/Mediator.SourceGenerator/Implementation/Analysis/CompilationAnalyzer.cs b/src/Mediator.SourceGenerator/Implementation/Analysis/CompilationAnalyzer.cs index d4e3aae8..81bce7ff 100644 --- a/src/Mediator.SourceGenerator/Implementation/Analysis/CompilationAnalyzer.cs +++ b/src/Mediator.SourceGenerator/Implementation/Analysis/CompilationAnalyzer.cs @@ -26,6 +26,7 @@ internal sealed class CompilationAnalyzer private readonly HashSet _notificationMessageHandlers; private readonly List _pipelineBehaviors; private Queue? _configuredAssemblies; + private HashSet? _includeTypesForGeneration; public ImmutableArray RequestMessageHandlerWrappers; @@ -760,6 +761,34 @@ bool ProcessInterface( } else { + // Filter based on IncludeTypesForGeneration if configured + // Only filter if the collection is not null AND has items + // Empty collection or null means no filtering (include all) + if (_includeTypesForGeneration is not null && _includeTypesForGeneration.Count > 0) + { + var implementsMarkerInterface = false; + foreach (var markerInterface in _includeTypesForGeneration) + { + // Check if typeSymbol implements the marker interface + if ( + typeSymbol.AllInterfaces.Any(i => + _symbolComparer.Equals(i.OriginalDefinition, markerInterface) + ) + ) + { + implementsMarkerInterface = true; + break; + } + } + + if (!implementsMarkerInterface) + { + // Remove the message if it doesn't implement any marker interface + _requestMessages.Remove(message); + return true; // Continue processing, just skip this message + } + } + if (mapping.TryGetValue(typeSymbol, out var requestMessageHandlerObj)) { mapping[typeSymbol] = null; @@ -1428,6 +1457,40 @@ CancellationToken cancellationToken _configuredAssemblies.Enqueue(assemblySymbol.GlobalNamespace); } } + else if (opt == "IncludeTypesForGeneration") + { + if (_includeTypesForGeneration is not null) + { + ReportDiagnostic( + assignment.Left.GetLocation(), + (in CompilationAnalyzerContext c, Location l) => + c.ReportInvalidCodeBasedConfiguration( + l, + "IncludeTypesForGeneration can only be configured once" + ) + ); + return false; + } + + _includeTypesForGeneration = new(_symbolComparer); + var typeOfExpressions = assignment.Right.DescendantNodes().OfType().ToArray(); + + foreach (var typeOfExpression in typeOfExpressions) + { + var typeInfo = semanticModel.GetTypeInfo(typeOfExpression.Type, cancellationToken); + if (typeInfo.Type is not INamedTypeSymbol typeSymbol) + { + ReportDiagnostic( + typeOfExpression.Type.GetLocation(), + (in CompilationAnalyzerContext c, Location l) => + c.ReportInvalidCodeBasedConfiguration(l, $"Could not resolve type: {typeOfExpression.Type}") + ); + continue; + } + + _includeTypesForGeneration.Add(typeSymbol.OriginalDefinition); + } + } else if (opt == "PipelineBehaviors" || opt == "StreamPipelineBehaviors") { var interfaceName = opt == "PipelineBehaviors" ? "IPipelineBehavior" : "IStreamPipelineBehavior"; diff --git a/src/Mediator.SourceGenerator/Implementation/resources/MediatorOptions.sbn-cs b/src/Mediator.SourceGenerator/Implementation/resources/MediatorOptions.sbn-cs index 7e22bd54..0f2b79f9 100644 --- a/src/Mediator.SourceGenerator/Implementation/resources/MediatorOptions.sbn-cs +++ b/src/Mediator.SourceGenerator/Implementation/resources/MediatorOptions.sbn-cs @@ -61,6 +61,15 @@ namespace Mediator /// public global::System.Collections.Generic.IReadOnlyList Assemblies { get; set; } = new global::Mediator.AssemblyReference[0]; + /// + /// The collection of marker interface types to filter which request types are included for generation. + /// When specified with one or more types, only request types that implement IRequest AND at least one of the specified marker interfaces will be included. + /// When empty or not configured, all discovered request types will be included (no filtering). + /// This is useful for modular monolith scenarios where you want to generate code only for requests belonging to specific modules. + /// Example: options.IncludeTypesForGeneration = [typeof(IApi1Request)] will only generate code for requests that implement IApi1Request. + /// + public global::System.Collections.Generic.IReadOnlyList IncludeTypesForGeneration { get; set; } = new global::System.Type[0]; + /// /// The collection of types of pipeline behaviors to register in DI. /// When the type is an unconstructed generic type, the source generator will register all the constructed types of the generic type (open generics that is supported during AoT). diff --git a/test/Mediator.SourceGenerator.Tests/ConfigurationTests.cs b/test/Mediator.SourceGenerator.Tests/ConfigurationTests.cs index cd46d435..6288433f 100644 --- a/test/Mediator.SourceGenerator.Tests/ConfigurationTests.cs +++ b/test/Mediator.SourceGenerator.Tests/ConfigurationTests.cs @@ -1,3 +1,4 @@ +using System.Linq; using System.Threading.Tasks; namespace Mediator.SourceGenerator.Tests; @@ -808,4 +809,285 @@ [EnumeratorCancellation] CancellationToken cancellationToken await inputCompilation.AssertAndVerify(); } + + [Fact] + public async Task Test_IncludeTypesForGeneration_SingleType() + { + var inputCompilation = Fixture.CreateLibrary( + """ + using System; + using System.Threading; + using System.Threading.Tasks; + using Mediator; + using Microsoft.Extensions.DependencyInjection; + + namespace TestCode; + + public class Program + { + public static void Main() + { + var services = new ServiceCollection(); + + services.AddMediator(options => + { + options.IncludeTypesForGeneration = + [ + typeof(IApi1Request), + ]; + }); + } + } + + public interface IApi1Request { } + + public readonly record struct Request1(Guid Id) : IRequest, IApi1Request; + public readonly record struct Response1(Guid Id); + public sealed class Request1Handler : IRequestHandler + { + public ValueTask Handle(Request1 request, CancellationToken cancellationToken) => + new ValueTask(new Response1(request.Id)); + } + + public readonly record struct Request2(Guid Id) : IRequest; + public readonly record struct Response2(Guid Id); + public sealed class Request2Handler : IRequestHandler + { + public ValueTask Handle(Request2 request, CancellationToken cancellationToken) => + new ValueTask(new Response2(request.Id)); + } + """ + ); + + await inputCompilation.AssertAndVerify( + Assertions.CompilesWithoutDiagnostics, + result => + { + var model = result.Generator.CompilationModel; + Assert.NotNull(model); + // Should only have Request1 (implements IApi1Request), not Request2 + Assert.Single(model.RequestMessages); + Assert.Equal("Request1", model.RequestMessages[0].Name); + } + ); + } + + [Fact] + public async Task Test_IncludeTypesForGeneration_MultipleTypes() + { + var inputCompilation = Fixture.CreateLibrary( + """ + using System; + using System.Threading; + using System.Threading.Tasks; + using Mediator; + using Microsoft.Extensions.DependencyInjection; + + namespace TestCode; + + public class Program + { + public static void Main() + { + var services = new ServiceCollection(); + + services.AddMediator(options => + { + options.IncludeTypesForGeneration = + [ + typeof(IApi1Request), + typeof(IApi2Request), + ]; + }); + } + } + + public interface IApi1Request { } + public interface IApi2Request { } + + public readonly record struct Request1(Guid Id) : IRequest, IApi1Request; + public readonly record struct Response1(Guid Id); + public sealed class Request1Handler : IRequestHandler + { + public ValueTask Handle(Request1 request, CancellationToken cancellationToken) => + new ValueTask(new Response1(request.Id)); + } + + public readonly record struct Request2(Guid Id) : IRequest, IApi2Request; + public readonly record struct Response2(Guid Id); + public sealed class Request2Handler : IRequestHandler + { + public ValueTask Handle(Request2 request, CancellationToken cancellationToken) => + new ValueTask(new Response2(request.Id)); + } + + public readonly record struct Request3(Guid Id) : IRequest, IApi1Request, IApi2Request; + public readonly record struct Response3(Guid Id); + public sealed class Request3Handler : IRequestHandler + { + public ValueTask Handle(Request3 request, CancellationToken cancellationToken) => + new ValueTask(new Response3(request.Id)); + } + + public readonly record struct Request4(Guid Id) : IRequest; + public readonly record struct Response4(Guid Id); + public sealed class Request4Handler : IRequestHandler + { + public ValueTask Handle(Request4 request, CancellationToken cancellationToken) => + new ValueTask(new Response4(request.Id)); + } + """ + ); + + await inputCompilation.AssertAndVerify( + Assertions.CompilesWithoutDiagnostics, + result => + { + var model = result.Generator.CompilationModel; + Assert.NotNull(model); + // Should have Request1, Request2, and Request3 (all implement marker interfaces) + // Should NOT have Request4 (doesn't implement any marker interface) + Assert.Equal(3, model.RequestMessages.Count); + var requestNames = new[] + { + model.RequestMessages[0].Name, + model.RequestMessages[1].Name, + model.RequestMessages[2].Name, + } + .OrderBy(n => n) + .ToArray(); + Assert.Equal(new[] { "Request1", "Request2", "Request3" }, requestNames); + } + ); + } + + [Fact] + public async Task Test_IncludeTypesForGeneration_EmptyList() + { + var inputCompilation = Fixture.CreateLibrary( + """ + using System; + using System.Threading; + using System.Threading.Tasks; + using Mediator; + using Microsoft.Extensions.DependencyInjection; + + namespace TestCode; + + public class Program + { + public static void Main() + { + var services = new ServiceCollection(); + + services.AddMediator(options => + { + options.IncludeTypesForGeneration = []; + }); + } + } + + public readonly record struct Request1(Guid Id) : IRequest; + public readonly record struct Response1(Guid Id); + public sealed class Request1Handler : IRequestHandler + { + public ValueTask Handle(Request1 request, CancellationToken cancellationToken) => + new ValueTask(new Response1(request.Id)); + } + """ + ); + + await inputCompilation.AssertAndVerify( + Assertions.CompilesWithoutDiagnostics, + result => + { + var model = result.Generator.CompilationModel; + Assert.NotNull(model); + // Empty filter list means no filtering - all requests should be included + Assert.Single(model.RequestMessages); + Assert.Equal("Request1", model.RequestMessages[0].Name); + } + ); + } + + [Fact] + public async Task Test_IncludeTypesForGeneration_ModularMonolith_TwoAPIs() + { + // This test demonstrates a modular monolith scenario with two APIs + // sharing the same codebase but only generating mediator code for their respective requests + + var inputCompilation = Fixture.CreateLibrary( + """ + using System; + using System.Threading; + using System.Threading.Tasks; + using Mediator; + using Microsoft.Extensions.DependencyInjection; + + namespace TestCode; + + // Marker interfaces for different APIs/modules + public interface IApi1Request { } + public interface IApi2Request { } + + public class Api1Program + { + public static void Main() + { + var services = new ServiceCollection(); + + // API1 only generates code for IApi1Request handlers + services.AddMediator(options => + { + options.Namespace = "Api1"; + options.IncludeTypesForGeneration = [typeof(IApi1Request)]; + }); + } + } + + // Shared across both APIs + public readonly record struct SharedRequest(Guid Id) : IRequest, IApi1Request, IApi2Request; + public readonly record struct SharedResponse(Guid Id); + public sealed class SharedRequestHandler : IRequestHandler + { + public ValueTask Handle(SharedRequest request, CancellationToken cancellationToken) => + new ValueTask(new SharedResponse(request.Id)); + } + + // API1 only + public readonly record struct Api1OnlyRequest(Guid Id) : IRequest, IApi1Request; + public readonly record struct Api1Response(Guid Id); + public sealed class Api1OnlyRequestHandler : IRequestHandler + { + public ValueTask Handle(Api1OnlyRequest request, CancellationToken cancellationToken) => + new ValueTask(new Api1Response(request.Id)); + } + + // API2 only - should NOT be included in API1's generated code + public readonly record struct Api2OnlyRequest(Guid Id) : IRequest, IApi2Request; + public readonly record struct Api2Response(Guid Id); + public sealed class Api2OnlyRequestHandler : IRequestHandler + { + public ValueTask Handle(Api2OnlyRequest request, CancellationToken cancellationToken) => + new ValueTask(new Api2Response(request.Id)); + } + """ + ); + + await inputCompilation.AssertAndVerify( + Assertions.CompilesWithoutDiagnostics, + result => + { + var model = result.Generator.CompilationModel; + Assert.NotNull(model); + // Should only have SharedRequest and Api1OnlyRequest + // Should NOT have Api2OnlyRequest + Assert.Equal(2, model.RequestMessages.Count); + var requestNames = new[] { model.RequestMessages[0].Name, model.RequestMessages[1].Name } + .OrderBy(n => n) + .ToArray(); + Assert.Equal(new[] { "Api1OnlyRequest", "SharedRequest" }, requestNames); + } + ); + } } diff --git a/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_EmptyList#Mediator.g.verified.cs b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_EmptyList#Mediator.g.verified.cs new file mode 100644 index 00000000..eab39806 --- /dev/null +++ b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_EmptyList#Mediator.g.verified.cs @@ -0,0 +1,1266 @@ +//HintName: Mediator.g.cs +// +// Generated by the Mediator source generator. +// + +#pragma warning disable CS8019 // Unused usings +#pragma warning disable CS8321 // Unused local function +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using System.Linq; + +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// DI extensions for Mediator. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public static class MediatorDependencyInjectionExtensions + { + /// + /// Adds the Mediator implementation and handlers of your application. + /// + public static IServiceCollection AddMediator(this IServiceCollection services) + { + return AddMediator(services, null); + } + + /// + /// Adds the Mediator implementation and handlers of your application, with specified options. + /// + public static IServiceCollection AddMediator(this IServiceCollection services, global::System.Action? options) + { + var opts = new global::Mediator.MediatorOptions(); + if (options != null) + options(opts); + + var configuredViaAttribute = false; + if (opts.ServiceLifetime != global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton && !configuredViaAttribute) + { + var errMsg = "Invalid configuration detected for Mediator. "; + errMsg += "Generated code for 'Singleton' lifetime, but got '" + opts.ServiceLifetime + "' lifetime from options. "; + errMsg += "This means that the source generator hasn't seen the 'AddMediator' method call during compilation. "; + errMsg += "Make sure that the 'AddMediator' method is called from the project that references the Mediator.SourceGenerator package."; + throw new global::System.Exception(errMsg); + } + + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Mediator), typeof(global::Mediator.Mediator), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IMediator), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ISender), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register handlers for request messages + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.Request1Handler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.RequestHandlerWrapper), typeof(global::Mediator.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register the notification publisher that was configured + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ForeachAwaitPublisher), typeof(global::Mediator.ForeachAwaitPublisher), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.INotificationPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register internal components + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.IContainerProbe), typeof(global::Mediator.Internals.ContainerProbe0), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.IContainerProbe), typeof(global::Mediator.Internals.ContainerProbe1), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.ContainerMetadata), typeof(global::Mediator.Internals.ContainerMetadata), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + return services; + + } + } +} + +namespace Mediator.Internals +{ + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface INotificationHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IRequestHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class RequestHandlerWrapper : IRequestHandlerBase + where TRequest : global::Mediator.IRequest + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public RequestHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamRequestHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamRequestHandlerWrapper : IStreamRequestHandlerBase + where TRequest : global::Mediator.IStreamRequest + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamRequestHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface ICommandHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class CommandHandlerWrapper : ICommandHandlerBase + where TRequest : global::Mediator.ICommand + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public CommandHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamCommandHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamCommandHandlerWrapper : IStreamCommandHandlerBase + where TRequest : global::Mediator.IStreamCommand + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamCommandHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IQueryHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class QueryHandlerWrapper : IQueryHandlerBase + where TRequest : global::Mediator.IQuery + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public QueryHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamQueryHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamQueryHandlerWrapper : IStreamQueryHandlerBase + where TRequest : global::Mediator.IStreamQuery + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamQueryHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class NotificationHandlerWrapper : INotificationHandlerBase + where TNotification : global::Mediator.INotification + { + private global::Mediator.ForeachAwaitPublisher _publisher = null!; + private global::Mediator.INotificationHandler[] _handlers = null!; + + public NotificationHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + _publisher = containerMetadata.NotificationPublisher; + var handlers = sp.GetServices>(); + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + handlers is global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = global::System.Runtime.CompilerServices.Unsafe.As[]>( + handlers + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + handlers is not global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = handlers.ToArray(); + } + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handlers = _handlers; + if (handlers.Length == 0) + { + return default; + } + return _publisher.Publish( + new global::Mediator.NotificationHandlers(handlers, isArray: true), + notification, + cancellationToken + ); + } + + public global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TNotification)notification, cancellationToken); + } + } + + internal interface IContainerProbe { } + internal sealed class ContainerProbe0 : IContainerProbe { } + internal sealed class ContainerProbe1 : IContainerProbe { } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class ContainerMetadata + { + public readonly bool ServicesUnderlyingTypeIsArray; + + public readonly global::System.Collections.Frozen.FrozenDictionary RequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary CommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary QueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary StreamRequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamCommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamQueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary NotificationHandlerWrappers; + + public readonly global::Mediator.Internals.RequestHandlerWrapper Wrapper_For_TestCode_Request1; + + public readonly global::Mediator.ForeachAwaitPublisher NotificationPublisher; + + public ContainerMetadata(global::System.IServiceProvider sp) + { + ServicesUnderlyingTypeIsArray = sp.GetServices() is global::Mediator.Internals.IContainerProbe[]; + + NotificationPublisher = sp.GetRequiredService(); + + var requestHandlerTypes = new global::System.Collections.Generic.Dictionary(1); + var commandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var queryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + requestHandlerTypes.Add(typeof(global::TestCode.Request1), sp.GetRequiredService>().Init(this, sp)); + RequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(requestHandlerTypes); + CommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(commandHandlerTypes); + QueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(queryHandlerTypes); + + var streamRequestHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamCommandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamQueryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + StreamRequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamRequestHandlerTypes); + StreamCommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamCommandHandlerTypes); + StreamQueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamQueryHandlerTypes); + + var notificationHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + NotificationHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(notificationHandlerTypes); + + Wrapper_For_TestCode_Request1 = sp.GetRequiredService>().Init(this, sp); + } + } +} + +namespace Mediator +{ + /// + /// Generated code for Mediator implementation. + /// This type is also registered as a DI service. + /// Can be used directly for high performance scenarios. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public sealed partial class Mediator : global::Mediator.IMediator, global::Mediator.ISender, global::Mediator.IPublisher + { + internal readonly global::System.IServiceProvider Services; + private FastLazyValue _containerMetadata; + private global::Mediator.ForeachAwaitPublisher? _notificationPublisher; + internal global::Mediator.ForeachAwaitPublisher NotificationPublisher + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_notificationPublisher == null) + _notificationPublisher = _containerMetadata.Value.NotificationPublisher; + return _notificationPublisher!; + } + } + private bool? _servicesUnderlyingTypeIsArray; + internal bool ServicesUnderlyingTypeIsArray + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_servicesUnderlyingTypeIsArray == null) + _servicesUnderlyingTypeIsArray = _containerMetadata.Value.ServicesUnderlyingTypeIsArray; + return _servicesUnderlyingTypeIsArray!.Value; + } + } + + /// + /// The lifetime of Mediator-related service registrations in DI container. + /// + public const global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; + + /// + /// The caching mode configuration for Mediator handler resolution. + /// + public const global::Mediator.CachingMode CachingMode = global::Mediator.CachingMode.Eager; + + /// + /// The name of the notification publisher service that was configured. + /// + public const string NotificationPublisherName = "ForeachAwaitPublisher"; + + /// + /// The total number of Mediator messages that were discovered. + /// + public const int TotalMessages = 1; + + /// + /// Constructor for DI, should not be used by consumer. + /// + public Mediator(global::System.IServiceProvider sp) + { + Services = sp; + _containerMetadata = new FastLazyValue( + self => self.Services.GetRequiredService(), + this + ); + } + + private struct FastLazyValue + { + private const long UNINIT = 0; + private const long INITING = 1; + private const long INITD = 2; + + private global::System.Func _generator; + private long _state; + private T _value; + private TArg _arg; + + public T Value + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_state != INITD) + return ValueSlow; + + return _value; + } + } + + private T ValueSlow + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + get + { + var prevState = global::System.Threading.Interlocked.CompareExchange(ref _state, INITING, UNINIT); + switch (prevState) + { + case INITD: + // Someone has already completed init + return _value; + case INITING: + // Wait for someone else to complete + var spinWait = default(global::System.Threading.SpinWait); + while (global::System.Threading.Interlocked.Read(ref _state) < INITD) + spinWait.SpinOnce(); + return _value; + case UNINIT: + _value = _generator(_arg); + global::System.Threading.Interlocked.Exchange(ref _state, INITD); + return _value; + } + + return _value; + } + } + + public FastLazyValue(global::System.Func generator, TArg arg) + { + _generator = generator; + _state = UNINIT; + _value = default!; + _arg = arg; + } + } + + + + /// + /// Send a request of type global::TestCode.Request1. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.Request1 request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_Request1.Handle(request, cancellationToken); + } + + /// + /// Send request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.Request1 r: + { + if (typeof(TResponse) == typeof(global::TestCode.Response1)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.Request1 r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default!; + } + } + } + + /// + /// Create stream for request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamRequest(request, nameof(request)); + return default!; + } + + /// + /// Send command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming command + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default!; + } + + /// + /// Create stream for command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamCommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamCommand(command, nameof(command)); + return default!; + } + + /// + /// Send query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming query + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default!; + } + + /// + /// Create stream for query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamQuery(query, nameof(query)); + return default!; + } + + /// + /// Send message. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Awaitable task + public async global::System.Threading.Tasks.ValueTask Send( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (message) + { + case global::Mediator.IBaseRequest request: + switch (request) + { + case global::TestCode.Request1 r: return await Send(r, cancellationToken); + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + case global::Mediator.IBaseCommand command: + switch (command) + { + default: + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + } + case global::Mediator.IBaseQuery query: + switch (query) + { + default: + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + } + default: + ThrowInvalidMessage(message, nameof(message)); + return default!; + } + } + + /// + /// Create stream. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamMessage(message, nameof(message)); + return default!; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// Drops messages + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + object notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + where TNotification : global::Mediator.INotification + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowMissingHandler(object msg) => + throw new global::Mediator.MissingMessageHandlerException(msg); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IStreamMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowArgumentNull(string? paramName) => + throw new global::System.ArgumentNullException(paramName); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T msg) => + throw new global::Mediator.InvalidMessageException(msg); + + private static void ThrowIfNull(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + } + + private static void ThrowInvalidNotification(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + else if (!(argument is global::Mediator.INotification)) + ThrowInvalidMessage(argument); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowAggregateException(global::System.Collections.Generic.List exceptions) => + throw new global::System.AggregateException(exceptions); + + private static void MaybeThrowAggregateException(global::System.Collections.Generic.List? exceptions) + { + if (exceptions != null) + { + ThrowAggregateException(exceptions); + } + } + } +} diff --git a/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_ModularMonolith_TwoAPIs#Mediator.g.verified.cs b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_ModularMonolith_TwoAPIs#Mediator.g.verified.cs new file mode 100644 index 00000000..e11199c7 --- /dev/null +++ b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_ModularMonolith_TwoAPIs#Mediator.g.verified.cs @@ -0,0 +1,1300 @@ +//HintName: Mediator.g.cs +// +// Generated by the Mediator source generator. +// + +#pragma warning disable CS8019 // Unused usings +#pragma warning disable CS8321 // Unused local function +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using System.Linq; + +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// DI extensions for Mediator. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public static class MediatorDependencyInjectionExtensions + { + /// + /// Adds the Mediator implementation and handlers of your application. + /// + public static IServiceCollection AddMediator(this IServiceCollection services) + { + return AddMediator(services, null); + } + + /// + /// Adds the Mediator implementation and handlers of your application, with specified options. + /// + public static IServiceCollection AddMediator(this IServiceCollection services, global::System.Action? options) + { + var opts = new global::Mediator.MediatorOptions(); + if (options != null) + options(opts); + + var configuredViaAttribute = false; + if (opts.ServiceLifetime != global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton && !configuredViaAttribute) + { + var errMsg = "Invalid configuration detected for Mediator. "; + errMsg += "Generated code for 'Singleton' lifetime, but got '" + opts.ServiceLifetime + "' lifetime from options. "; + errMsg += "This means that the source generator hasn't seen the 'AddMediator' method call during compilation. "; + errMsg += "Make sure that the 'AddMediator' method is called from the project that references the Mediator.SourceGenerator package."; + throw new global::System.Exception(errMsg); + } + + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Api1.Mediator), typeof(global::Api1.Mediator), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IMediator), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ISender), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register handlers for request messages + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.SharedRequestHandler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Api1.Internals.RequestHandlerWrapper), typeof(global::Api1.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.Api1OnlyRequestHandler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Api1.Internals.RequestHandlerWrapper), typeof(global::Api1.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register the notification publisher that was configured + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ForeachAwaitPublisher), typeof(global::Mediator.ForeachAwaitPublisher), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.INotificationPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register internal components + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Api1.Internals.IContainerProbe), typeof(global::Api1.Internals.ContainerProbe0), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Api1.Internals.IContainerProbe), typeof(global::Api1.Internals.ContainerProbe1), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Api1.Internals.ContainerMetadata), typeof(global::Api1.Internals.ContainerMetadata), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + return services; + + } + } +} + +namespace Api1.Internals +{ + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface INotificationHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IRequestHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class RequestHandlerWrapper : IRequestHandlerBase + where TRequest : global::Mediator.IRequest + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public RequestHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamRequestHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamRequestHandlerWrapper : IStreamRequestHandlerBase + where TRequest : global::Mediator.IStreamRequest + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamRequestHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface ICommandHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class CommandHandlerWrapper : ICommandHandlerBase + where TRequest : global::Mediator.ICommand + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public CommandHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamCommandHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamCommandHandlerWrapper : IStreamCommandHandlerBase + where TRequest : global::Mediator.IStreamCommand + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamCommandHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IQueryHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class QueryHandlerWrapper : IQueryHandlerBase + where TRequest : global::Mediator.IQuery + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public QueryHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamQueryHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamQueryHandlerWrapper : IStreamQueryHandlerBase + where TRequest : global::Mediator.IStreamQuery + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamQueryHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class NotificationHandlerWrapper : INotificationHandlerBase + where TNotification : global::Mediator.INotification + { + private global::Mediator.ForeachAwaitPublisher _publisher = null!; + private global::Mediator.INotificationHandler[] _handlers = null!; + + public NotificationHandlerWrapper Init( + global::Api1.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + _publisher = containerMetadata.NotificationPublisher; + var handlers = sp.GetServices>(); + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + handlers is global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = global::System.Runtime.CompilerServices.Unsafe.As[]>( + handlers + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + handlers is not global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = handlers.ToArray(); + } + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handlers = _handlers; + if (handlers.Length == 0) + { + return default; + } + return _publisher.Publish( + new global::Mediator.NotificationHandlers(handlers, isArray: true), + notification, + cancellationToken + ); + } + + public global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TNotification)notification, cancellationToken); + } + } + + internal interface IContainerProbe { } + internal sealed class ContainerProbe0 : IContainerProbe { } + internal sealed class ContainerProbe1 : IContainerProbe { } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class ContainerMetadata + { + public readonly bool ServicesUnderlyingTypeIsArray; + + public readonly global::System.Collections.Frozen.FrozenDictionary RequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary CommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary QueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary StreamRequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamCommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamQueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary NotificationHandlerWrappers; + + public readonly global::Api1.Internals.RequestHandlerWrapper Wrapper_For_TestCode_SharedRequest; + public readonly global::Api1.Internals.RequestHandlerWrapper Wrapper_For_TestCode_Api1OnlyRequest; + + public readonly global::Mediator.ForeachAwaitPublisher NotificationPublisher; + + public ContainerMetadata(global::System.IServiceProvider sp) + { + ServicesUnderlyingTypeIsArray = sp.GetServices() is global::Api1.Internals.IContainerProbe[]; + + NotificationPublisher = sp.GetRequiredService(); + + var requestHandlerTypes = new global::System.Collections.Generic.Dictionary(2); + var commandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var queryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + requestHandlerTypes.Add(typeof(global::TestCode.SharedRequest), sp.GetRequiredService>().Init(this, sp)); + requestHandlerTypes.Add(typeof(global::TestCode.Api1OnlyRequest), sp.GetRequiredService>().Init(this, sp)); + RequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(requestHandlerTypes); + CommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(commandHandlerTypes); + QueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(queryHandlerTypes); + + var streamRequestHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamCommandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamQueryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + StreamRequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamRequestHandlerTypes); + StreamCommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamCommandHandlerTypes); + StreamQueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamQueryHandlerTypes); + + var notificationHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + NotificationHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(notificationHandlerTypes); + + Wrapper_For_TestCode_SharedRequest = sp.GetRequiredService>().Init(this, sp); + Wrapper_For_TestCode_Api1OnlyRequest = sp.GetRequiredService>().Init(this, sp); + } + } +} + +namespace Api1 +{ + /// + /// Generated code for Mediator implementation. + /// This type is also registered as a DI service. + /// Can be used directly for high performance scenarios. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public sealed partial class Mediator : global::Mediator.IMediator, global::Mediator.ISender, global::Mediator.IPublisher + { + internal readonly global::System.IServiceProvider Services; + private FastLazyValue _containerMetadata; + private global::Mediator.ForeachAwaitPublisher? _notificationPublisher; + internal global::Mediator.ForeachAwaitPublisher NotificationPublisher + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_notificationPublisher == null) + _notificationPublisher = _containerMetadata.Value.NotificationPublisher; + return _notificationPublisher!; + } + } + private bool? _servicesUnderlyingTypeIsArray; + internal bool ServicesUnderlyingTypeIsArray + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_servicesUnderlyingTypeIsArray == null) + _servicesUnderlyingTypeIsArray = _containerMetadata.Value.ServicesUnderlyingTypeIsArray; + return _servicesUnderlyingTypeIsArray!.Value; + } + } + + /// + /// The lifetime of Mediator-related service registrations in DI container. + /// + public const global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; + + /// + /// The caching mode configuration for Mediator handler resolution. + /// + public const global::Mediator.CachingMode CachingMode = global::Mediator.CachingMode.Eager; + + /// + /// The name of the notification publisher service that was configured. + /// + public const string NotificationPublisherName = "ForeachAwaitPublisher"; + + /// + /// The total number of Mediator messages that were discovered. + /// + public const int TotalMessages = 2; + + /// + /// Constructor for DI, should not be used by consumer. + /// + public Mediator(global::System.IServiceProvider sp) + { + Services = sp; + _containerMetadata = new FastLazyValue( + self => self.Services.GetRequiredService(), + this + ); + } + + private struct FastLazyValue + { + private const long UNINIT = 0; + private const long INITING = 1; + private const long INITD = 2; + + private global::System.Func _generator; + private long _state; + private T _value; + private TArg _arg; + + public T Value + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_state != INITD) + return ValueSlow; + + return _value; + } + } + + private T ValueSlow + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + get + { + var prevState = global::System.Threading.Interlocked.CompareExchange(ref _state, INITING, UNINIT); + switch (prevState) + { + case INITD: + // Someone has already completed init + return _value; + case INITING: + // Wait for someone else to complete + var spinWait = default(global::System.Threading.SpinWait); + while (global::System.Threading.Interlocked.Read(ref _state) < INITD) + spinWait.SpinOnce(); + return _value; + case UNINIT: + _value = _generator(_arg); + global::System.Threading.Interlocked.Exchange(ref _state, INITD); + return _value; + } + + return _value; + } + } + + public FastLazyValue(global::System.Func generator, TArg arg) + { + _generator = generator; + _state = UNINIT; + _value = default!; + _arg = arg; + } + } + + + + /// + /// Send a request of type global::TestCode.SharedRequest. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.SharedRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_SharedRequest.Handle(request, cancellationToken); + } + + /// + /// Send a request of type global::TestCode.Api1OnlyRequest. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.Api1OnlyRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_Api1OnlyRequest.Handle(request, cancellationToken); + } + + /// + /// Send request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.SharedRequest r: + { + if (typeof(TResponse) == typeof(global::TestCode.SharedResponse)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + case global::TestCode.Api1OnlyRequest r: + { + if (typeof(TResponse) == typeof(global::TestCode.Api1Response)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.SharedRequest r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + case global::TestCode.Api1OnlyRequest r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default!; + } + } + } + + /// + /// Create stream for request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamRequest(request, nameof(request)); + return default!; + } + + /// + /// Send command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming command + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default!; + } + + /// + /// Create stream for command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamCommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamCommand(command, nameof(command)); + return default!; + } + + /// + /// Send query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming query + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default!; + } + + /// + /// Create stream for query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamQuery(query, nameof(query)); + return default!; + } + + /// + /// Send message. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Awaitable task + public async global::System.Threading.Tasks.ValueTask Send( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (message) + { + case global::Mediator.IBaseRequest request: + switch (request) + { + case global::TestCode.SharedRequest r: return await Send(r, cancellationToken); + case global::TestCode.Api1OnlyRequest r: return await Send(r, cancellationToken); + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + case global::Mediator.IBaseCommand command: + switch (command) + { + default: + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + } + case global::Mediator.IBaseQuery query: + switch (query) + { + default: + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + } + default: + ThrowInvalidMessage(message, nameof(message)); + return default!; + } + } + + /// + /// Create stream. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamMessage(message, nameof(message)); + return default!; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// Drops messages + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + object notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + where TNotification : global::Mediator.INotification + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowMissingHandler(object msg) => + throw new global::Mediator.MissingMessageHandlerException(msg); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IStreamMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowArgumentNull(string? paramName) => + throw new global::System.ArgumentNullException(paramName); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T msg) => + throw new global::Mediator.InvalidMessageException(msg); + + private static void ThrowIfNull(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + } + + private static void ThrowInvalidNotification(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + else if (!(argument is global::Mediator.INotification)) + ThrowInvalidMessage(argument); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowAggregateException(global::System.Collections.Generic.List exceptions) => + throw new global::System.AggregateException(exceptions); + + private static void MaybeThrowAggregateException(global::System.Collections.Generic.List? exceptions) + { + if (exceptions != null) + { + ThrowAggregateException(exceptions); + } + } + } +} diff --git a/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_MultipleTypes#Mediator.g.verified.cs b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_MultipleTypes#Mediator.g.verified.cs new file mode 100644 index 00000000..f02b4daf --- /dev/null +++ b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_MultipleTypes#Mediator.g.verified.cs @@ -0,0 +1,1334 @@ +//HintName: Mediator.g.cs +// +// Generated by the Mediator source generator. +// + +#pragma warning disable CS8019 // Unused usings +#pragma warning disable CS8321 // Unused local function +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using System.Linq; + +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// DI extensions for Mediator. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public static class MediatorDependencyInjectionExtensions + { + /// + /// Adds the Mediator implementation and handlers of your application. + /// + public static IServiceCollection AddMediator(this IServiceCollection services) + { + return AddMediator(services, null); + } + + /// + /// Adds the Mediator implementation and handlers of your application, with specified options. + /// + public static IServiceCollection AddMediator(this IServiceCollection services, global::System.Action? options) + { + var opts = new global::Mediator.MediatorOptions(); + if (options != null) + options(opts); + + var configuredViaAttribute = false; + if (opts.ServiceLifetime != global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton && !configuredViaAttribute) + { + var errMsg = "Invalid configuration detected for Mediator. "; + errMsg += "Generated code for 'Singleton' lifetime, but got '" + opts.ServiceLifetime + "' lifetime from options. "; + errMsg += "This means that the source generator hasn't seen the 'AddMediator' method call during compilation. "; + errMsg += "Make sure that the 'AddMediator' method is called from the project that references the Mediator.SourceGenerator package."; + throw new global::System.Exception(errMsg); + } + + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Mediator), typeof(global::Mediator.Mediator), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IMediator), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ISender), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register handlers for request messages + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.Request1Handler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.RequestHandlerWrapper), typeof(global::Mediator.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.Request2Handler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.RequestHandlerWrapper), typeof(global::Mediator.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.Request3Handler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.RequestHandlerWrapper), typeof(global::Mediator.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register the notification publisher that was configured + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ForeachAwaitPublisher), typeof(global::Mediator.ForeachAwaitPublisher), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.INotificationPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register internal components + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.IContainerProbe), typeof(global::Mediator.Internals.ContainerProbe0), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.IContainerProbe), typeof(global::Mediator.Internals.ContainerProbe1), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.ContainerMetadata), typeof(global::Mediator.Internals.ContainerMetadata), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + return services; + + } + } +} + +namespace Mediator.Internals +{ + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface INotificationHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IRequestHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class RequestHandlerWrapper : IRequestHandlerBase + where TRequest : global::Mediator.IRequest + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public RequestHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamRequestHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamRequestHandlerWrapper : IStreamRequestHandlerBase + where TRequest : global::Mediator.IStreamRequest + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamRequestHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface ICommandHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class CommandHandlerWrapper : ICommandHandlerBase + where TRequest : global::Mediator.ICommand + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public CommandHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamCommandHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamCommandHandlerWrapper : IStreamCommandHandlerBase + where TRequest : global::Mediator.IStreamCommand + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamCommandHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IQueryHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class QueryHandlerWrapper : IQueryHandlerBase + where TRequest : global::Mediator.IQuery + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public QueryHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamQueryHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamQueryHandlerWrapper : IStreamQueryHandlerBase + where TRequest : global::Mediator.IStreamQuery + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamQueryHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class NotificationHandlerWrapper : INotificationHandlerBase + where TNotification : global::Mediator.INotification + { + private global::Mediator.ForeachAwaitPublisher _publisher = null!; + private global::Mediator.INotificationHandler[] _handlers = null!; + + public NotificationHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + _publisher = containerMetadata.NotificationPublisher; + var handlers = sp.GetServices>(); + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + handlers is global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = global::System.Runtime.CompilerServices.Unsafe.As[]>( + handlers + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + handlers is not global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = handlers.ToArray(); + } + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handlers = _handlers; + if (handlers.Length == 0) + { + return default; + } + return _publisher.Publish( + new global::Mediator.NotificationHandlers(handlers, isArray: true), + notification, + cancellationToken + ); + } + + public global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TNotification)notification, cancellationToken); + } + } + + internal interface IContainerProbe { } + internal sealed class ContainerProbe0 : IContainerProbe { } + internal sealed class ContainerProbe1 : IContainerProbe { } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class ContainerMetadata + { + public readonly bool ServicesUnderlyingTypeIsArray; + + public readonly global::System.Collections.Frozen.FrozenDictionary RequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary CommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary QueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary StreamRequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamCommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamQueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary NotificationHandlerWrappers; + + public readonly global::Mediator.Internals.RequestHandlerWrapper Wrapper_For_TestCode_Request1; + public readonly global::Mediator.Internals.RequestHandlerWrapper Wrapper_For_TestCode_Request2; + public readonly global::Mediator.Internals.RequestHandlerWrapper Wrapper_For_TestCode_Request3; + + public readonly global::Mediator.ForeachAwaitPublisher NotificationPublisher; + + public ContainerMetadata(global::System.IServiceProvider sp) + { + ServicesUnderlyingTypeIsArray = sp.GetServices() is global::Mediator.Internals.IContainerProbe[]; + + NotificationPublisher = sp.GetRequiredService(); + + var requestHandlerTypes = new global::System.Collections.Generic.Dictionary(3); + var commandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var queryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + requestHandlerTypes.Add(typeof(global::TestCode.Request1), sp.GetRequiredService>().Init(this, sp)); + requestHandlerTypes.Add(typeof(global::TestCode.Request2), sp.GetRequiredService>().Init(this, sp)); + requestHandlerTypes.Add(typeof(global::TestCode.Request3), sp.GetRequiredService>().Init(this, sp)); + RequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(requestHandlerTypes); + CommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(commandHandlerTypes); + QueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(queryHandlerTypes); + + var streamRequestHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamCommandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamQueryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + StreamRequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamRequestHandlerTypes); + StreamCommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamCommandHandlerTypes); + StreamQueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamQueryHandlerTypes); + + var notificationHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + NotificationHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(notificationHandlerTypes); + + Wrapper_For_TestCode_Request1 = sp.GetRequiredService>().Init(this, sp); + Wrapper_For_TestCode_Request2 = sp.GetRequiredService>().Init(this, sp); + Wrapper_For_TestCode_Request3 = sp.GetRequiredService>().Init(this, sp); + } + } +} + +namespace Mediator +{ + /// + /// Generated code for Mediator implementation. + /// This type is also registered as a DI service. + /// Can be used directly for high performance scenarios. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public sealed partial class Mediator : global::Mediator.IMediator, global::Mediator.ISender, global::Mediator.IPublisher + { + internal readonly global::System.IServiceProvider Services; + private FastLazyValue _containerMetadata; + private global::Mediator.ForeachAwaitPublisher? _notificationPublisher; + internal global::Mediator.ForeachAwaitPublisher NotificationPublisher + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_notificationPublisher == null) + _notificationPublisher = _containerMetadata.Value.NotificationPublisher; + return _notificationPublisher!; + } + } + private bool? _servicesUnderlyingTypeIsArray; + internal bool ServicesUnderlyingTypeIsArray + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_servicesUnderlyingTypeIsArray == null) + _servicesUnderlyingTypeIsArray = _containerMetadata.Value.ServicesUnderlyingTypeIsArray; + return _servicesUnderlyingTypeIsArray!.Value; + } + } + + /// + /// The lifetime of Mediator-related service registrations in DI container. + /// + public const global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; + + /// + /// The caching mode configuration for Mediator handler resolution. + /// + public const global::Mediator.CachingMode CachingMode = global::Mediator.CachingMode.Eager; + + /// + /// The name of the notification publisher service that was configured. + /// + public const string NotificationPublisherName = "ForeachAwaitPublisher"; + + /// + /// The total number of Mediator messages that were discovered. + /// + public const int TotalMessages = 3; + + /// + /// Constructor for DI, should not be used by consumer. + /// + public Mediator(global::System.IServiceProvider sp) + { + Services = sp; + _containerMetadata = new FastLazyValue( + self => self.Services.GetRequiredService(), + this + ); + } + + private struct FastLazyValue + { + private const long UNINIT = 0; + private const long INITING = 1; + private const long INITD = 2; + + private global::System.Func _generator; + private long _state; + private T _value; + private TArg _arg; + + public T Value + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_state != INITD) + return ValueSlow; + + return _value; + } + } + + private T ValueSlow + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + get + { + var prevState = global::System.Threading.Interlocked.CompareExchange(ref _state, INITING, UNINIT); + switch (prevState) + { + case INITD: + // Someone has already completed init + return _value; + case INITING: + // Wait for someone else to complete + var spinWait = default(global::System.Threading.SpinWait); + while (global::System.Threading.Interlocked.Read(ref _state) < INITD) + spinWait.SpinOnce(); + return _value; + case UNINIT: + _value = _generator(_arg); + global::System.Threading.Interlocked.Exchange(ref _state, INITD); + return _value; + } + + return _value; + } + } + + public FastLazyValue(global::System.Func generator, TArg arg) + { + _generator = generator; + _state = UNINIT; + _value = default!; + _arg = arg; + } + } + + + + /// + /// Send a request of type global::TestCode.Request1. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.Request1 request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_Request1.Handle(request, cancellationToken); + } + + /// + /// Send a request of type global::TestCode.Request2. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.Request2 request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_Request2.Handle(request, cancellationToken); + } + + /// + /// Send a request of type global::TestCode.Request3. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.Request3 request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_Request3.Handle(request, cancellationToken); + } + + /// + /// Send request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.Request1 r: + { + if (typeof(TResponse) == typeof(global::TestCode.Response1)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + case global::TestCode.Request2 r: + { + if (typeof(TResponse) == typeof(global::TestCode.Response2)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + case global::TestCode.Request3 r: + { + if (typeof(TResponse) == typeof(global::TestCode.Response3)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.Request1 r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + case global::TestCode.Request2 r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + case global::TestCode.Request3 r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default!; + } + } + } + + /// + /// Create stream for request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamRequest(request, nameof(request)); + return default!; + } + + /// + /// Send command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming command + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default!; + } + + /// + /// Create stream for command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamCommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamCommand(command, nameof(command)); + return default!; + } + + /// + /// Send query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming query + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default!; + } + + /// + /// Create stream for query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamQuery(query, nameof(query)); + return default!; + } + + /// + /// Send message. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Awaitable task + public async global::System.Threading.Tasks.ValueTask Send( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (message) + { + case global::Mediator.IBaseRequest request: + switch (request) + { + case global::TestCode.Request1 r: return await Send(r, cancellationToken); + case global::TestCode.Request2 r: return await Send(r, cancellationToken); + case global::TestCode.Request3 r: return await Send(r, cancellationToken); + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + case global::Mediator.IBaseCommand command: + switch (command) + { + default: + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + } + case global::Mediator.IBaseQuery query: + switch (query) + { + default: + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + } + default: + ThrowInvalidMessage(message, nameof(message)); + return default!; + } + } + + /// + /// Create stream. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamMessage(message, nameof(message)); + return default!; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// Drops messages + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + object notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + where TNotification : global::Mediator.INotification + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowMissingHandler(object msg) => + throw new global::Mediator.MissingMessageHandlerException(msg); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IStreamMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowArgumentNull(string? paramName) => + throw new global::System.ArgumentNullException(paramName); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T msg) => + throw new global::Mediator.InvalidMessageException(msg); + + private static void ThrowIfNull(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + } + + private static void ThrowInvalidNotification(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + else if (!(argument is global::Mediator.INotification)) + ThrowInvalidMessage(argument); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowAggregateException(global::System.Collections.Generic.List exceptions) => + throw new global::System.AggregateException(exceptions); + + private static void MaybeThrowAggregateException(global::System.Collections.Generic.List? exceptions) + { + if (exceptions != null) + { + ThrowAggregateException(exceptions); + } + } + } +} diff --git a/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_SingleType#Mediator.g.verified.cs b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_SingleType#Mediator.g.verified.cs new file mode 100644 index 00000000..eab39806 --- /dev/null +++ b/test/Mediator.SourceGenerator.Tests/_snapshots/ConfigurationTests.Test_IncludeTypesForGeneration_SingleType#Mediator.g.verified.cs @@ -0,0 +1,1266 @@ +//HintName: Mediator.g.cs +// +// Generated by the Mediator source generator. +// + +#pragma warning disable CS8019 // Unused usings +#pragma warning disable CS8321 // Unused local function +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + +#nullable enable + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using System.Linq; + +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// DI extensions for Mediator. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public static class MediatorDependencyInjectionExtensions + { + /// + /// Adds the Mediator implementation and handlers of your application. + /// + public static IServiceCollection AddMediator(this IServiceCollection services) + { + return AddMediator(services, null); + } + + /// + /// Adds the Mediator implementation and handlers of your application, with specified options. + /// + public static IServiceCollection AddMediator(this IServiceCollection services, global::System.Action? options) + { + var opts = new global::Mediator.MediatorOptions(); + if (options != null) + options(opts); + + var configuredViaAttribute = false; + if (opts.ServiceLifetime != global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton && !configuredViaAttribute) + { + var errMsg = "Invalid configuration detected for Mediator. "; + errMsg += "Generated code for 'Singleton' lifetime, but got '" + opts.ServiceLifetime + "' lifetime from options. "; + errMsg += "This means that the source generator hasn't seen the 'AddMediator' method call during compilation. "; + errMsg += "Make sure that the 'AddMediator' method is called from the project that references the Mediator.SourceGenerator package."; + throw new global::System.Exception(errMsg); + } + + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Mediator), typeof(global::Mediator.Mediator), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IMediator), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ISender), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register handlers for request messages + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.IRequestHandler), typeof(global::TestCode.Request1Handler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.RequestHandlerWrapper), typeof(global::Mediator.Internals.RequestHandlerWrapper), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register the notification publisher that was configured + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.ForeachAwaitPublisher), typeof(global::Mediator.ForeachAwaitPublisher), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.TryAdd(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.INotificationPublisher), sp => sp.GetRequiredService(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + // Register internal components + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.IContainerProbe), typeof(global::Mediator.Internals.ContainerProbe0), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.IContainerProbe), typeof(global::Mediator.Internals.ContainerProbe1), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + services.Add(new global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(global::Mediator.Internals.ContainerMetadata), typeof(global::Mediator.Internals.ContainerMetadata), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); + + return services; + + } + } +} + +namespace Mediator.Internals +{ + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface INotificationHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ); + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IRequestHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class RequestHandlerWrapper : IRequestHandlerBase + where TRequest : global::Mediator.IRequest + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public RequestHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamRequestHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamRequestHandlerWrapper : IStreamRequestHandlerBase + where TRequest : global::Mediator.IStreamRequest + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamRequestHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface ICommandHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class CommandHandlerWrapper : ICommandHandlerBase + where TRequest : global::Mediator.ICommand + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public CommandHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.ICommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamCommandHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamCommandHandlerWrapper : IStreamCommandHandlerBase + where TRequest : global::Mediator.IStreamCommand + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamCommandHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamCommand request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IQueryHandlerBase : IMessageHandlerBase + { + global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class QueryHandlerWrapper : IQueryHandlerBase + where TRequest : global::Mediator.IQuery + { + private global::Mediator.MessageHandlerDelegate _rootHandler = null!; + + public QueryHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.MessageHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Threading.Tasks.ValueTask Handle( + global::Mediator.IQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Threading.Tasks.ValueTask Handle( + object request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return await Handle((TRequest)request, cancellationToken); + } + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + internal interface IStreamQueryHandlerBase : IStreamMessageHandlerBase + { + global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ); + } + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class StreamQueryHandlerWrapper : IStreamQueryHandlerBase + where TRequest : global::Mediator.IStreamQuery + { + private global::Mediator.StreamHandlerDelegate _rootHandler = null!; + + public StreamQueryHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + var concreteHandler = sp.GetRequiredService>(); + var pipelineBehaviours = sp.GetServices>(); + var handler = (global::Mediator.StreamHandlerDelegate)concreteHandler.Handle; + + global::Mediator.IStreamPipelineBehavior[] pipelineBehavioursArray; + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = global::System.Runtime.CompilerServices.Unsafe.As[]>( + pipelineBehaviours + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + pipelineBehaviours is not global::Mediator.IStreamPipelineBehavior[] + ); + pipelineBehavioursArray = pipelineBehaviours.ToArray(); + } + + for (int i = pipelineBehavioursArray.Length - 1; i >= 0; i--) + { + var pipeline = pipelineBehavioursArray[i]; + var handlerCopy = handler; + var pipelineCopy = pipeline; + handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, handlerCopy, cancellationToken); + } + + _rootHandler = handler; + return this; + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + TRequest request, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handler = _rootHandler; + return handler(request, cancellationToken); + } + + public global::System.Collections.Generic.IAsyncEnumerable Handle( + global::Mediator.IStreamQuery request, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TRequest)request, cancellationToken); + } + + public async global::System.Collections.Generic.IAsyncEnumerable Handle( + object request, + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken + ) + { + await foreach (var el in Handle((TRequest)request, cancellationToken)) + yield return el; + } + } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class NotificationHandlerWrapper : INotificationHandlerBase + where TNotification : global::Mediator.INotification + { + private global::Mediator.ForeachAwaitPublisher _publisher = null!; + private global::Mediator.INotificationHandler[] _handlers = null!; + + public NotificationHandlerWrapper Init( + global::Mediator.Internals.ContainerMetadata containerMetadata, + global::System.IServiceProvider sp + ) + { + _publisher = containerMetadata.NotificationPublisher; + var handlers = sp.GetServices>(); + if (containerMetadata.ServicesUnderlyingTypeIsArray) + { + global::System.Diagnostics.Debug.Assert( + handlers is global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = global::System.Runtime.CompilerServices.Unsafe.As[]>( + handlers + ); + } + else + { + global::System.Diagnostics.Debug.Assert( + handlers is not global::Mediator.INotificationHandler[], + $"Unexpected type: {handlers.GetType()}" + ); + _handlers = handlers.ToArray(); + } + return this; + } + + public global::System.Threading.Tasks.ValueTask Handle( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + var handlers = _handlers; + if (handlers.Length == 0) + { + return default; + } + return _publisher.Publish( + new global::Mediator.NotificationHandlers(handlers, isArray: true), + notification, + cancellationToken + ); + } + + public global::System.Threading.Tasks.ValueTask Handle( + object notification, + global::System.Threading.CancellationToken cancellationToken + ) + { + return Handle((TNotification)notification, cancellationToken); + } + } + + internal interface IContainerProbe { } + internal sealed class ContainerProbe0 : IContainerProbe { } + internal sealed class ContainerProbe1 : IContainerProbe { } + + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + internal sealed class ContainerMetadata + { + public readonly bool ServicesUnderlyingTypeIsArray; + + public readonly global::System.Collections.Frozen.FrozenDictionary RequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary CommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary QueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary StreamRequestHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamCommandHandlerWrappers; + public readonly global::System.Collections.Frozen.FrozenDictionary StreamQueryHandlerWrappers; + + public readonly global::System.Collections.Frozen.FrozenDictionary NotificationHandlerWrappers; + + public readonly global::Mediator.Internals.RequestHandlerWrapper Wrapper_For_TestCode_Request1; + + public readonly global::Mediator.ForeachAwaitPublisher NotificationPublisher; + + public ContainerMetadata(global::System.IServiceProvider sp) + { + ServicesUnderlyingTypeIsArray = sp.GetServices() is global::Mediator.Internals.IContainerProbe[]; + + NotificationPublisher = sp.GetRequiredService(); + + var requestHandlerTypes = new global::System.Collections.Generic.Dictionary(1); + var commandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var queryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + requestHandlerTypes.Add(typeof(global::TestCode.Request1), sp.GetRequiredService>().Init(this, sp)); + RequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(requestHandlerTypes); + CommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(commandHandlerTypes); + QueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(queryHandlerTypes); + + var streamRequestHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamCommandHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + var streamQueryHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + StreamRequestHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamRequestHandlerTypes); + StreamCommandHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamCommandHandlerTypes); + StreamQueryHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(streamQueryHandlerTypes); + + var notificationHandlerTypes = new global::System.Collections.Generic.Dictionary(0); + NotificationHandlerWrappers = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(notificationHandlerTypes); + + Wrapper_For_TestCode_Request1 = sp.GetRequiredService>().Init(this, sp); + } + } +} + +namespace Mediator +{ + /// + /// Generated code for Mediator implementation. + /// This type is also registered as a DI service. + /// Can be used directly for high performance scenarios. + /// + [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "3.1.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.Diagnostics.DebuggerStepThroughAttribute] + public sealed partial class Mediator : global::Mediator.IMediator, global::Mediator.ISender, global::Mediator.IPublisher + { + internal readonly global::System.IServiceProvider Services; + private FastLazyValue _containerMetadata; + private global::Mediator.ForeachAwaitPublisher? _notificationPublisher; + internal global::Mediator.ForeachAwaitPublisher NotificationPublisher + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_notificationPublisher == null) + _notificationPublisher = _containerMetadata.Value.NotificationPublisher; + return _notificationPublisher!; + } + } + private bool? _servicesUnderlyingTypeIsArray; + internal bool ServicesUnderlyingTypeIsArray + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_servicesUnderlyingTypeIsArray == null) + _servicesUnderlyingTypeIsArray = _containerMetadata.Value.ServicesUnderlyingTypeIsArray; + return _servicesUnderlyingTypeIsArray!.Value; + } + } + + /// + /// The lifetime of Mediator-related service registrations in DI container. + /// + public const global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; + + /// + /// The caching mode configuration for Mediator handler resolution. + /// + public const global::Mediator.CachingMode CachingMode = global::Mediator.CachingMode.Eager; + + /// + /// The name of the notification publisher service that was configured. + /// + public const string NotificationPublisherName = "ForeachAwaitPublisher"; + + /// + /// The total number of Mediator messages that were discovered. + /// + public const int TotalMessages = 1; + + /// + /// Constructor for DI, should not be used by consumer. + /// + public Mediator(global::System.IServiceProvider sp) + { + Services = sp; + _containerMetadata = new FastLazyValue( + self => self.Services.GetRequiredService(), + this + ); + } + + private struct FastLazyValue + { + private const long UNINIT = 0; + private const long INITING = 1; + private const long INITD = 2; + + private global::System.Func _generator; + private long _state; + private T _value; + private TArg _arg; + + public T Value + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + if (_state != INITD) + return ValueSlow; + + return _value; + } + } + + private T ValueSlow + { + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + get + { + var prevState = global::System.Threading.Interlocked.CompareExchange(ref _state, INITING, UNINIT); + switch (prevState) + { + case INITD: + // Someone has already completed init + return _value; + case INITING: + // Wait for someone else to complete + var spinWait = default(global::System.Threading.SpinWait); + while (global::System.Threading.Interlocked.Read(ref _state) < INITD) + spinWait.SpinOnce(); + return _value; + case UNINIT: + _value = _generator(_arg); + global::System.Threading.Interlocked.Exchange(ref _state, INITD); + return _value; + } + + return _value; + } + } + + public FastLazyValue(global::System.Func generator, TArg arg) + { + _generator = generator; + _state = UNINIT; + _value = default!; + _arg = arg; + } + } + + + + /// + /// Send a request of type global::TestCode.Request1. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::TestCode.Request1 request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + return _containerMetadata.Value.Wrapper_For_TestCode_Request1.Handle(request, cancellationToken); + } + + /// + /// Send request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming request + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.Request1 r: + { + if (typeof(TResponse) == typeof(global::TestCode.Response1)) + { + var task = Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As, global::System.Threading.Tasks.ValueTask>(ref task); + } + return SendAsync(request, cancellationToken); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (request) + { + case global::TestCode.Request1 r: + { + var response = await Send(r, cancellationToken); + return global::System.Runtime.CompilerServices.Unsafe.As(ref response); + } + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default!; + } + } + } + + /// + /// Create stream for request. + /// Throws if message is null. + /// Throws if request does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamRequest request, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamRequest(request, nameof(request)); + return default!; + } + + /// + /// Send command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming command + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.ICommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidCommand(command, nameof(command)); + return default!; + } + + /// + /// Create stream for command. + /// Throws if message is null. + /// Throws if command does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamCommand command, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamCommand(command, nameof(command)); + return default!; + } + + /// + /// Send query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming query + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Send( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + + private async global::System.Threading.Tasks.ValueTask SendAsync( + global::Mediator.IQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidQuery(query, nameof(query)); + return default!; + } + + /// + /// Create stream for query. + /// Throws if message is null. + /// Throws if query does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + global::Mediator.IStreamQuery query, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamQuery(query, nameof(query)); + return default!; + } + + /// + /// Send message. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Awaitable task + public async global::System.Threading.Tasks.ValueTask Send( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + switch (message) + { + case global::Mediator.IBaseRequest request: + switch (request) + { + case global::TestCode.Request1 r: return await Send(r, cancellationToken); + default: + { + ThrowInvalidRequest(request, nameof(request)); + return default; + } + } + case global::Mediator.IBaseCommand command: + switch (command) + { + default: + { + ThrowInvalidCommand(command, nameof(command)); + return default; + } + } + case global::Mediator.IBaseQuery query: + switch (query) + { + default: + { + ThrowInvalidQuery(query, nameof(query)); + return default; + } + } + default: + ThrowInvalidMessage(message, nameof(message)); + return default!; + } + } + + /// + /// Create stream. + /// Throws if message is null. + /// Throws if message does not implement . + /// Throws if no handler is registered. + /// + /// Incoming message + /// Cancellation token + /// Async enumerable + public global::System.Collections.Generic.IAsyncEnumerable CreateStream( + object message, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidStreamMessage(message, nameof(message)); + return default!; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// Drops messages + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + object notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + + /// + /// Publish notification. + /// Throws if message is null. + /// Throws if notification does not implement . + /// Throws if handlers throw exception(s). + /// + /// Incoming notification + /// Cancellation token + /// Awaitable task + public global::System.Threading.Tasks.ValueTask Publish( + TNotification notification, + global::System.Threading.CancellationToken cancellationToken = default + ) + where TNotification : global::Mediator.INotification + { + ThrowInvalidNotification(notification, nameof(notification)); + return default; + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowMissingHandler(object msg) => + throw new global::Mediator.MissingMessageHandlerException(msg); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamMessage(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IStreamMessage)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamRequest(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamRequest)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamCommand(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamCommand)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidStreamQuery(T? msg, string? paramName = null) + { + if (msg == null) + ThrowArgumentNull(paramName); + else if (!(msg is global::Mediator.IBaseStreamQuery)) + ThrowInvalidMessage(msg); + else + ThrowMissingHandler(msg); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowArgumentNull(string? paramName) => + throw new global::System.ArgumentNullException(paramName); + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowInvalidMessage(T msg) => + throw new global::Mediator.InvalidMessageException(msg); + + private static void ThrowIfNull(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + } + + private static void ThrowInvalidNotification(T? argument, string paramName) + { + if (argument == null) + ThrowArgumentNull(paramName); + else if (!(argument is global::Mediator.INotification)) + ThrowInvalidMessage(argument); + } + +#if NETSTANDARD2_1_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] +#endif + private static void ThrowAggregateException(global::System.Collections.Generic.List exceptions) => + throw new global::System.AggregateException(exceptions); + + private static void MaybeThrowAggregateException(global::System.Collections.Generic.List? exceptions) + { + if (exceptions != null) + { + ThrowAggregateException(exceptions); + } + } + } +}