RSCG – Mediator
RSCG – Mediator
name | Mediator |
nuget |
https://www.nuget.org/packages/Mediator.SourceGenerator https://www.nuget.org/packages/Mediator.Abstractions |
link | https://github.com/martinothamar/Mediator |
author | Martin Othamar |
Gnerating mediator data without reflection
This is how you can use Mediator .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> </PropertyGroup> <ItemGroup> <PackageReference Include="Mediator.Abstractions" Version="2.1.5" /> <PackageReference Include="Mediator.SourceGenerator" Version="2.1.5" OutputItemType="Analyzer"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> </ItemGroup> </Project>
The code that you will use is
Console.WriteLine("Hello, World!"); var services = new ServiceCollection(); services.AddMediator(); services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(GenericLoggerHandler<,>)); // This will run 1st var serviceProvider = services.BuildServiceProvider(); var mediator = serviceProvider.GetRequiredService<IMediator>(); var id = Guid.NewGuid(); var request = new Ping(id); var response = await mediator.Send(request); Console.WriteLine("-----------------------------------"); Console.WriteLine("ID: " + id); Console.WriteLine(request); Console.WriteLine(response);
public sealed class GenericLoggerHandler<TMessage, TResponse> : IPipelineBehavior<TMessage, TResponse> where TMessage : IMessage { public async ValueTask<TResponse> Handle(TMessage message, CancellationToken cancellationToken, MessageHandlerDelegate<TMessage, TResponse> next) { Console.WriteLine("1) Running logger handler"); try { var response = await next(message, cancellationToken); Console.WriteLine("5) No error!"); return response; } catch (Exception ex) { Console.WriteLine("error:"+ex.Message); throw; } } }
public sealed record Ping(Guid Id) : IRequest<Pong>; public sealed record Pong(Guid Id); public sealed class PingHandler : IRequestHandler<Ping, Pong> { public ValueTask<Pong> Handle(Ping request, CancellationToken cancellationToken) { Console.WriteLine("4) Returning pong!"); return new ValueTask<Pong>(new Pong(request.Id)); } }
The code that is generated is
// <auto-generated> // Generated by the Mediator source generator. // </auto-generated> #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 using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System.Linq; using SD = global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor; namespace Microsoft.Extensions.DependencyInjection { /// <summary> /// DI extensions for Mediator. /// </summary> [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] public static class MediatorDependencyInjectionExtensions { /// <summary> /// Adds the Mediator implementation and handlers of your application. /// </summary> public static IServiceCollection AddMediator(this IServiceCollection services) { return AddMediator(services, null); } internal sealed class Dummy { } /// <summary> /// Adds the Mediator implementation and handlers of your application, with specified options. /// </summary> public static IServiceCollection AddMediator(this IServiceCollection services, global::System.Action<global::Mediator.MediatorOptions> 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 SD(typeof(global::Mediator.Mediator), typeof(global::Mediator.Mediator), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); services.TryAdd(new SD(typeof(global::Mediator.IMediator), sp => sp.GetRequiredService<global::Mediator.Mediator>(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); services.TryAdd(new SD(typeof(global::Mediator.ISender), sp => sp.GetRequiredService<global::Mediator.Mediator>(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); services.TryAdd(new SD(typeof(global::Mediator.IPublisher), sp => sp.GetRequiredService<global::Mediator.Mediator>(), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); services.TryAdd(new SD(typeof(global::PingHandler), typeof(global::PingHandler), global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton)); services.Add(new SD( typeof(global::Mediator.RequestClassHandlerWrapper<global::Ping, global::Pong>), sp => { return new global::Mediator.RequestClassHandlerWrapper<global::Ping, global::Pong>( sp.GetRequiredService<global::PingHandler>(), sp.GetServices<global::Mediator.IPipelineBehavior<global::Ping, global::Pong>>() ); }, global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton )); services.AddSingleton<Dummy>(); return services; } } } namespace Mediator { [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class RequestClassHandlerWrapper<TRequest, TResponse> where TRequest : class, global::Mediator.IRequest<TResponse> { private readonly global::Mediator.MessageHandlerDelegate<TRequest, TResponse> _rootHandler; public RequestClassHandlerWrapper( global::Mediator.IRequestHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.MessageHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Threading.Tasks.ValueTask<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class RequestStructHandlerWrapper<TRequest, TResponse> where TRequest : struct, global::Mediator.IRequest<TResponse> { private readonly global::Mediator.MessageHandlerDelegate<TRequest, TResponse> _rootHandler; public RequestStructHandlerWrapper( global::Mediator.IRequestHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.MessageHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Threading.Tasks.ValueTask<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class StreamRequestClassHandlerWrapper<TRequest, TResponse> where TRequest : class, global::Mediator.IStreamRequest<TResponse> { private readonly global::Mediator.StreamHandlerDelegate<TRequest, TResponse> _rootHandler; public StreamRequestClassHandlerWrapper( global::Mediator.IStreamRequestHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IStreamPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.StreamHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Collections.Generic.IAsyncEnumerable<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class StreamRequestStructHandlerWrapper<TRequest, TResponse> where TRequest : struct, global::Mediator.IStreamRequest<TResponse> { private readonly global::Mediator.StreamHandlerDelegate<TRequest, TResponse> _rootHandler; public StreamRequestStructHandlerWrapper( global::Mediator.IStreamRequestHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IStreamPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.StreamHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Collections.Generic.IAsyncEnumerable<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class CommandClassHandlerWrapper<TRequest, TResponse> where TRequest : class, global::Mediator.ICommand<TResponse> { private readonly global::Mediator.MessageHandlerDelegate<TRequest, TResponse> _rootHandler; public CommandClassHandlerWrapper( global::Mediator.ICommandHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.MessageHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Threading.Tasks.ValueTask<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class CommandStructHandlerWrapper<TRequest, TResponse> where TRequest : struct, global::Mediator.ICommand<TResponse> { private readonly global::Mediator.MessageHandlerDelegate<TRequest, TResponse> _rootHandler; public CommandStructHandlerWrapper( global::Mediator.ICommandHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.MessageHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Threading.Tasks.ValueTask<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class StreamCommandClassHandlerWrapper<TRequest, TResponse> where TRequest : class, global::Mediator.IStreamCommand<TResponse> { private readonly global::Mediator.StreamHandlerDelegate<TRequest, TResponse> _rootHandler; public StreamCommandClassHandlerWrapper( global::Mediator.IStreamCommandHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IStreamPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.StreamHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Collections.Generic.IAsyncEnumerable<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class StreamCommandStructHandlerWrapper<TRequest, TResponse> where TRequest : struct, global::Mediator.IStreamCommand<TResponse> { private readonly global::Mediator.StreamHandlerDelegate<TRequest, TResponse> _rootHandler; public StreamCommandStructHandlerWrapper( global::Mediator.IStreamCommandHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IStreamPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.StreamHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Collections.Generic.IAsyncEnumerable<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class QueryClassHandlerWrapper<TRequest, TResponse> where TRequest : class, global::Mediator.IQuery<TResponse> { private readonly global::Mediator.MessageHandlerDelegate<TRequest, TResponse> _rootHandler; public QueryClassHandlerWrapper( global::Mediator.IQueryHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.MessageHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Threading.Tasks.ValueTask<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class QueryStructHandlerWrapper<TRequest, TResponse> where TRequest : struct, global::Mediator.IQuery<TResponse> { private readonly global::Mediator.MessageHandlerDelegate<TRequest, TResponse> _rootHandler; public QueryStructHandlerWrapper( global::Mediator.IQueryHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.MessageHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Threading.Tasks.ValueTask<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class StreamQueryClassHandlerWrapper<TRequest, TResponse> where TRequest : class, global::Mediator.IStreamQuery<TResponse> { private readonly global::Mediator.StreamHandlerDelegate<TRequest, TResponse> _rootHandler; public StreamQueryClassHandlerWrapper( global::Mediator.IStreamQueryHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IStreamPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.StreamHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Collections.Generic.IAsyncEnumerable<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerStepThroughAttribute] internal sealed class StreamQueryStructHandlerWrapper<TRequest, TResponse> where TRequest : struct, global::Mediator.IStreamQuery<TResponse> { private readonly global::Mediator.StreamHandlerDelegate<TRequest, TResponse> _rootHandler; public StreamQueryStructHandlerWrapper( global::Mediator.IStreamQueryHandler<TRequest, TResponse> concreteHandler, global::System.Collections.Generic.IEnumerable<global::Mediator.IStreamPipelineBehavior<TRequest, TResponse>> pipelineBehaviours ) { var handler = (global::Mediator.StreamHandlerDelegate<TRequest, TResponse>)concreteHandler.Handle; foreach (var pipeline in pipelineBehaviours.Reverse()) { var handlerCopy = handler; var pipelineCopy = pipeline; handler = (TRequest message, System.Threading.CancellationToken cancellationToken) => pipelineCopy.Handle(message, cancellationToken, handlerCopy); } _rootHandler = handler; } public global::System.Collections.Generic.IAsyncEnumerable<TResponse> Handle(TRequest request, global::System.Threading.CancellationToken cancellationToken) => _rootHandler(request, cancellationToken); } /// <summary> /// Generated code for Mediator implementation. /// This type is also registered as a DI service. /// Can be used directly for high performance scenarios. /// </summary> [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.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 { private readonly global::System.IServiceProvider _sp; private FastLazyValue<DICache> _diCacheLazy; /// <summary> /// The lifetime of Mediator-related service registrations in DI container. /// </summary> public static global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime { get; } = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; private readonly global::System.Func<global::System.Collections.Generic.IEnumerable<object>, int> _getServicesLength; /// <summary> /// Constructor for DI, should not be used by consumer. /// </summary> public Mediator(global::System.IServiceProvider sp) { _sp = sp; _diCacheLazy = new FastLazyValue<DICache>(() => new DICache(_sp)); global::System.Func<global::System.Collections.Generic.IEnumerable<object>, int> fastGetLength = s => ((object[])s).Length; global::System.Func<global::System.Collections.Generic.IEnumerable<object>, int> slowGetLength = s => s.Count(); var dummy = sp.GetServices<global::Microsoft.Extensions.DependencyInjection.MediatorDependencyInjectionExtensions.Dummy>(); _getServicesLength = dummy.GetType() == typeof(global::Microsoft.Extensions.DependencyInjection.MediatorDependencyInjectionExtensions.Dummy[]) ? fastGetLength : slowGetLength; } private struct FastLazyValue<T> where T : struct { private const long UNINIT = 0; private const long INITING = 1; private const long INITD = 2; private global::System.Func<T> _generator; private long _state; private T _value; 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(); global::System.Threading.Interlocked.Exchange(ref _state, INITD); return _value; } return _value; } } public FastLazyValue(global::System.Func<T> generator) { _generator = generator; _state = UNINIT; _value = default; } } private readonly struct DICache { private readonly global::System.IServiceProvider _sp; public readonly global::Mediator.RequestClassHandlerWrapper<global::Ping, global::Pong> Wrapper_For_Ping; public DICache(global::System.IServiceProvider sp) { _sp = sp; Wrapper_For_Ping = sp.GetRequiredService<global::Mediator.RequestClassHandlerWrapper<global::Ping, global::Pong>>(); } } /// <summary> /// Send a message of type global::Ping. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// </summary> /// <param name="message">Incoming message</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public global::System.Threading.Tasks.ValueTask<global::Pong> Send( global::Ping message, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowIfNull(message, nameof(message)); return _diCacheLazy.Value.Wrapper_For_Ping.Handle(message, cancellationToken); } /// <summary> /// Send request. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="request">Incoming request</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public global::System.Threading.Tasks.ValueTask<TResponse> Send<TResponse>( global::Mediator.IRequest<TResponse> request, global::System.Threading.CancellationToken cancellationToken = default ) { switch (request) { case global::Ping r: { if(typeof(TResponse) == typeof(global::Pong)) { var task = Send(r, cancellationToken); return global::System.Runtime.CompilerServices.Unsafe.As<global::System.Threading.Tasks.ValueTask<global::Pong>, global::System.Threading.Tasks.ValueTask<TResponse>>(ref task); } else { return SendAsync(request, cancellationToken); } } default: { ThrowArgumentNullOrInvalidMessage(request, nameof(request)); return default; } } } /// <summary> /// Send request. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="request">Incoming request</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> private async global::System.Threading.Tasks.ValueTask<TResponse> SendAsync<TResponse>( global::Mediator.IRequest<TResponse> request, global::System.Threading.CancellationToken cancellationToken = default ) { switch (request) { case global::Ping r: { var response = await Send(r, cancellationToken); return global::System.Runtime.CompilerServices.Unsafe.As<global::Pong, TResponse>(ref response); } default: { ThrowArgumentNullOrInvalidMessage(request, nameof(request)); return default; } } } /// <summary> /// Create stream for request. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="request">Incoming message</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Async enumerable</returns> public global::System.Collections.Generic.IAsyncEnumerable<TResponse> CreateStream<TResponse>( global::Mediator.IStreamRequest<TResponse> request, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(request); return default; } /// <summary> /// Send command. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="command">Incoming command</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public global::System.Threading.Tasks.ValueTask<TResponse> Send<TResponse>( global::Mediator.ICommand<TResponse> command, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(command); return default; } /// <summary> /// Send command. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="command">Incoming command</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> private async global::System.Threading.Tasks.ValueTask<TResponse> SendAsync<TResponse>( global::Mediator.ICommand<TResponse> command, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(command); return default; } /// <summary> /// Create stream for command. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="command">Incoming message</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Async enumerable</returns> public global::System.Collections.Generic.IAsyncEnumerable<TResponse> CreateStream<TResponse>( global::Mediator.IStreamCommand<TResponse> command, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(command); return default; } /// <summary> /// Send query. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="query">Incoming query</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public global::System.Threading.Tasks.ValueTask<TResponse> Send<TResponse>( global::Mediator.IQuery<TResponse> query, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(query); return default; } /// <summary> /// Send query. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="query">Incoming query</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> private async global::System.Threading.Tasks.ValueTask<TResponse> SendAsync<TResponse>( global::Mediator.IQuery<TResponse> query, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(query); return default; } /// <summary> /// Create stream for query. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="query">Incoming message</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Async enumerable</returns> public global::System.Collections.Generic.IAsyncEnumerable<TResponse> CreateStream<TResponse>( global::Mediator.IStreamQuery<TResponse> query, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(query); return default; } /// <summary> /// Send message. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="message">Incoming message</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public async global::System.Threading.Tasks.ValueTask<object> Send( object message, global::System.Threading.CancellationToken cancellationToken = default ) { switch (message) { case global::Ping m: return await Send(m, cancellationToken); default: { ThrowArgumentNullOrInvalidMessage(message as global::Mediator.IMessage, nameof(message)); return default; } } } /// <summary> /// Create stream. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// Throws <see cref="global::Mediator.MissingMessageHandlerException"/> if no handler is registered. /// </summary> /// <param name="message">Incoming message</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Async enumerable</returns> public global::System.Collections.Generic.IAsyncEnumerable<object> CreateStream( object message, global::System.Threading.CancellationToken cancellationToken = default ) { ThrowInvalidMessage(message as global::Mediator.IStreamMessage); return default; } /// <summary> /// Publish notification. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// </summary> /// <param name="notification">Incoming notification</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public global::System.Threading.Tasks.ValueTask Publish( object notification, global::System.Threading.CancellationToken cancellationToken = default ) { return default; } /// <summary> /// Publish notification. /// Throws <see cref="global::System.ArgumentNullException"/> if message is null. /// </summary> /// <param name="notification">Incoming notification</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Awaitable task</returns> public global::System.Threading.Tasks.ValueTask Publish<TNotification>( TNotification notification, global::System.Threading.CancellationToken cancellationToken = default ) where TNotification : global::Mediator.INotification { return default; } [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowInvalidMessage(object msg) => throw new global::Mediator.MissingMessageHandlerException(msg); [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowArgumentNull(string paramName) => throw new global::System.ArgumentNullException(paramName); private static void ThrowIfNull<T>(T argument, string paramName) { if (argument is null) { ThrowArgumentNull(paramName); } } [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowArgumentNullOrInvalidMessage(object msg, string paramName) { if (msg is null) { ThrowArgumentNull(paramName); } else { ThrowInvalidMessage(msg); } } [global::System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowAggregateException(global::System.Collections.Generic.List<global::System.Exception> exceptions) => throw new global::System.AggregateException(exceptions); private static void MaybeThrowAggregateException(global::System.Collections.Generic.List<global::System.Exception> exceptions) { if (exceptions != null) { ThrowAggregateException(exceptions); } } } }
// <auto-generated> // Generated by the Mediator source generator. // </auto-generated> namespace Mediator { /// <summary> /// Provide options for the Mediator source generator. /// </summary> [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] public sealed class MediatorOptions { /// <summary> /// The namespace in which the Mediator implementation is generated. /// </summary> public string Namespace { get; set; } = "Mediator"; /// <summary> /// The default lifetime of the services registered in the DI container by /// the Mediator source generator. /// Singleton by default. /// </summary> public global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime { get; set; } = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; } }
// <auto-generated> // Generated by the Mediator source generator. // </auto-generated> namespace Mediator { /// <summary> /// Provide options for the Mediator source generator. /// </summary> [global::System.AttributeUsage(global::System.AttributeTargets.Assembly, AllowMultiple = false)] [global::System.CodeDom.Compiler.GeneratedCode("Mediator.SourceGenerator", "2.1.0.0")] public sealed class MediatorOptionsAttribute : global::System.Attribute { /// <summary> /// The namespace in which the Mediator implementation is generated. /// </summary> public string Namespace { get; set; } = "Mediator"; /// <summary> /// The default lifetime of the services registered in the DI container by /// the Mediator source generator. /// Singleton by default. /// </summary> public global::Microsoft.Extensions.DependencyInjection.ServiceLifetime ServiceLifetime { get; set; } = global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton; } }
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Mediator
Leave a Reply