RSCG – Mediator
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