diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 28cd76b..a8f73bb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,6 +10,8 @@ on:
jobs:
build:
strategy:
+ matrix:
+ os: [windows-latest]
fail-fast: false
runs-on: windows-latest
steps:
@@ -17,6 +19,10 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
+ - name: Setup dotnet 6.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
- name: Build and Test
run: ./Build.ps1
shell: pwsh
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f56b564..62859bd 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -7,6 +7,8 @@ on:
jobs:
build:
strategy:
+ matrix:
+ os: [windows-latest]
fail-fast: false
runs-on: windows-latest
steps:
@@ -14,6 +16,10 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
+ - name: Setup dotnet 6.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
- name: Build and Test
run: ./Build.ps1
shell: pwsh
diff --git a/Directory.Build.props b/Directory.Build.props
index b453d01..e8054b8 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,7 +1,8 @@
Jimmy Bogard
- latest
+ 10.0
+ enable
$(NoWarn);1701;1702;1591
true
Apache-2.0
diff --git a/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatR.Extensions.Microsoft.DependencyInjection.csproj b/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatR.Extensions.Microsoft.DependencyInjection.csproj
index f439cfd..9c836eb 100644
--- a/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatR.Extensions.Microsoft.DependencyInjection.csproj
+++ b/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatR.Extensions.Microsoft.DependencyInjection.csproj
@@ -3,8 +3,9 @@
MediatR extensions for ASP.NET Core
Copyright Jimmy Bogard
- netstandard2.0
+ netstandard2.1
MediatR.Extensions.Microsoft.DependencyInjection
+ MediatR
MediatR.Extensions.Microsoft.DependencyInjection
mediator;request;response;queries;commands;notifications
true
@@ -25,10 +26,10 @@
-
-
-
-
+
+
+
+
diff --git a/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatrServiceConfiguration.cs b/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatrServiceConfiguration.cs
index 11dbdc1..a3908ad 100644
--- a/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatrServiceConfiguration.cs
+++ b/src/MediatR.Extensions.Microsoft.DependencyInjection/MediatrServiceConfiguration.cs
@@ -1,56 +1,49 @@
using Microsoft.Extensions.DependencyInjection;
-namespace MediatR
+namespace MediatR;
+
+using System;
+
+public class MediatRServiceConfiguration
{
- using System;
+ public Func TypeEvaluator { get; private set; } = t => true;
+ public Type MediatorImplementationType { get; private set; }
+ public ServiceLifetime Lifetime { get; private set; }
+ public RequestExceptionActionProcessorStrategy RequestExceptionActionProcessorStrategy { get; set; }
+
+ public MediatRServiceConfiguration()
+ {
+ MediatorImplementationType = typeof(Mediator);
+ Lifetime = ServiceLifetime.Transient;
+ }
+
+ public MediatRServiceConfiguration Using() where TMediator : IMediator
+ {
+ MediatorImplementationType = typeof(TMediator);
+ return this;
+ }
+
+ public MediatRServiceConfiguration AsSingleton()
+ {
+ Lifetime = ServiceLifetime.Singleton;
+ return this;
+ }
+
+ public MediatRServiceConfiguration AsScoped()
+ {
+ Lifetime = ServiceLifetime.Scoped;
+ return this;
+ }
- public enum RequestExceptionActionProcessorStrategy
+ public MediatRServiceConfiguration AsTransient()
{
- ApplyForUnhandledExceptions,
- ApplyForAllExceptions
+ Lifetime = ServiceLifetime.Transient;
+ return this;
}
- public class MediatRServiceConfiguration
+ public MediatRServiceConfiguration WithEvaluator(Func evaluator)
{
- public Func TypeEvaluator { get; private set; } = t => true;
- public Type MediatorImplementationType { get; private set; }
- public ServiceLifetime Lifetime { get; private set; }
- public RequestExceptionActionProcessorStrategy RequestExceptionActionProcessorStrategy { get; set; }
-
- public MediatRServiceConfiguration()
- {
- MediatorImplementationType = typeof(Mediator);
- Lifetime = ServiceLifetime.Transient;
- }
-
- public MediatRServiceConfiguration Using() where TMediator : IMediator
- {
- MediatorImplementationType = typeof(TMediator);
- return this;
- }
-
- public MediatRServiceConfiguration AsSingleton()
- {
- Lifetime = ServiceLifetime.Singleton;
- return this;
- }
-
- public MediatRServiceConfiguration AsScoped()
- {
- Lifetime = ServiceLifetime.Scoped;
- return this;
- }
-
- public MediatRServiceConfiguration AsTransient()
- {
- Lifetime = ServiceLifetime.Transient;
- return this;
- }
-
- public MediatRServiceConfiguration WithEvaluator(Func evaluator)
- {
- TypeEvaluator = evaluator;
- return this;
- }
+ TypeEvaluator = evaluator;
+ return this;
}
}
\ No newline at end of file
diff --git a/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs b/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs
index 132c662..39bae8c 100644
--- a/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs
+++ b/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs
@@ -6,258 +6,249 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
-namespace MediatR.Registration
+namespace MediatR.Registration;
+
+public static class ServiceRegistrar
{
- public static class ServiceRegistrar
+ public static void AddMediatRClasses(IServiceCollection services, IEnumerable assembliesToScan, MediatRServiceConfiguration configuration)
{
- public static void AddMediatRClasses(IServiceCollection services, IEnumerable assembliesToScan, MediatRServiceConfiguration configuration)
- {
- assembliesToScan = assembliesToScan.Distinct().ToArray();
+ assembliesToScan = assembliesToScan.Distinct().ToArray();
- ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>), services, assembliesToScan, false, configuration);
- ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>), services, assembliesToScan, true, configuration);
- ConnectImplementationsToTypesClosing(typeof(IRequestPreProcessor<>), services, assembliesToScan, true, configuration);
- ConnectImplementationsToTypesClosing(typeof(IRequestPostProcessor<,>), services, assembliesToScan, true, configuration);
- ConnectImplementationsToTypesClosing(typeof(IRequestExceptionHandler<,,>), services, assembliesToScan, true, configuration);
- ConnectImplementationsToTypesClosing(typeof(IRequestExceptionAction<,>), services, assembliesToScan, true, configuration);
+ ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>), services, assembliesToScan, false, configuration);
+ ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>), services, assembliesToScan, true, configuration);
+ ConnectImplementationsToTypesClosing(typeof(IStreamRequestHandler<,>), services, assembliesToScan, false, configuration);
+ ConnectImplementationsToTypesClosing(typeof(IRequestPreProcessor<>), services, assembliesToScan, true, configuration);
+ ConnectImplementationsToTypesClosing(typeof(IRequestPostProcessor<,>), services, assembliesToScan, true, configuration);
+ ConnectImplementationsToTypesClosing(typeof(IRequestExceptionHandler<,,>), services, assembliesToScan, true, configuration);
+ ConnectImplementationsToTypesClosing(typeof(IRequestExceptionAction<,>), services, assembliesToScan, true, configuration);
- var multiOpenInterfaces = new[]
- {
- typeof(INotificationHandler<>),
- typeof(IRequestPreProcessor<>),
- typeof(IRequestPostProcessor<,>),
- typeof(IRequestExceptionHandler<,,>),
- typeof(IRequestExceptionAction<,>)
- };
-
- foreach (var multiOpenInterface in multiOpenInterfaces)
- {
- var arity = multiOpenInterface.GetGenericArguments().Length;
+ var multiOpenInterfaces = new[]
+ {
+ typeof(INotificationHandler<>),
+ typeof(IRequestPreProcessor<>),
+ typeof(IRequestPostProcessor<,>),
+ typeof(IRequestExceptionHandler<,,>),
+ typeof(IRequestExceptionAction<,>)
+ };
+
+ foreach (var multiOpenInterface in multiOpenInterfaces)
+ {
+ var arity = multiOpenInterface.GetGenericArguments().Length;
- var concretions = assembliesToScan
- .SelectMany(a => a.DefinedTypes)
- .Where(type => type.FindInterfacesThatClose(multiOpenInterface).Any())
- .Where(type => type.IsConcrete() && type.IsOpenGeneric())
- .Where(type => type.GetGenericArguments().Length == arity)
- .Where(configuration.TypeEvaluator)
- .ToList();
+ var concretions = assembliesToScan
+ .SelectMany(a => a.DefinedTypes)
+ .Where(type => type.FindInterfacesThatClose(multiOpenInterface).Any())
+ .Where(type => type.IsConcrete() && type.IsOpenGeneric())
+ .Where(type => type.GetGenericArguments().Length == arity)
+ .Where(configuration.TypeEvaluator)
+ .ToList();
- foreach (var type in concretions)
- {
- services.AddTransient(multiOpenInterface, type);
- }
+ foreach (var type in concretions)
+ {
+ services.AddTransient(multiOpenInterface, type);
}
}
+ }
- ///
- /// Helper method use to differentiate behavior between request handlers and notification handlers.
- /// Request handlers should only be added once (so set addIfAlreadyExists to false)
- /// Notification handlers should all be added (set addIfAlreadyExists to true)
- ///
- ///
- ///
- ///
- ///
- private static void ConnectImplementationsToTypesClosing(Type openRequestInterface,
- IServiceCollection services,
- IEnumerable assembliesToScan,
- bool addIfAlreadyExists,
- MediatRServiceConfiguration configuration)
+ private static void ConnectImplementationsToTypesClosing(Type openRequestInterface,
+ IServiceCollection services,
+ IEnumerable assembliesToScan,
+ bool addIfAlreadyExists,
+ MediatRServiceConfiguration configuration)
+ {
+ var concretions = new List();
+ var interfaces = new List();
+ foreach (var type in assembliesToScan.SelectMany(a => a.DefinedTypes).Where(t => !t.IsOpenGeneric()).Where(configuration.TypeEvaluator))
{
- var concretions = new List();
- var interfaces = new List();
- foreach (var type in assembliesToScan.SelectMany(a => a.DefinedTypes).Where(t => !t.IsOpenGeneric()).Where(configuration.TypeEvaluator))
- {
- var interfaceTypes = type.FindInterfacesThatClose(openRequestInterface).ToArray();
- if (!interfaceTypes.Any()) continue;
+ var interfaceTypes = type.FindInterfacesThatClose(openRequestInterface).ToArray();
+ if (!interfaceTypes.Any()) continue;
- if (type.IsConcrete())
- {
- concretions.Add(type);
- }
-
- foreach (var interfaceType in interfaceTypes)
- {
- interfaces.Fill(interfaceType);
- }
+ if (type.IsConcrete())
+ {
+ concretions.Add(type);
}
- foreach (var @interface in interfaces)
+ foreach (var interfaceType in interfaceTypes)
{
- var exactMatches = concretions.Where(x => x.CanBeCastTo(@interface)).ToList();
- if (addIfAlreadyExists)
- {
- foreach (var type in exactMatches)
- {
- services.AddTransient(@interface, type);
- }
- }
- else
- {
- if (exactMatches.Count > 1)
- {
- exactMatches.RemoveAll(m => !IsMatchingWithInterface(m, @interface));
- }
-
- foreach (var type in exactMatches)
- {
- services.TryAddTransient(@interface, type);
- }
- }
-
- if (!@interface.IsOpenGeneric())
- {
- AddConcretionsThatCouldBeClosed(@interface, concretions, services);
- }
+ interfaces.Fill(interfaceType);
}
}
- private static bool IsMatchingWithInterface(Type handlerType, Type handlerInterface)
+ foreach (var @interface in interfaces)
{
- if (handlerType == null || handlerInterface == null)
+ var exactMatches = concretions.Where(x => x.CanBeCastTo(@interface)).ToList();
+ if (addIfAlreadyExists)
{
- return false;
- }
-
- if (handlerType.IsInterface)
- {
- if (handlerType.GenericTypeArguments.SequenceEqual(handlerInterface.GenericTypeArguments))
+ foreach (var type in exactMatches)
{
- return true;
+ services.AddTransient(@interface, type);
}
}
else
{
- return IsMatchingWithInterface(handlerType.GetInterface(handlerInterface.Name), handlerInterface);
- }
-
- return false;
- }
-
- private static void AddConcretionsThatCouldBeClosed(Type @interface, List concretions, IServiceCollection services)
- {
- foreach (var type in concretions
- .Where(x => x.IsOpenGeneric() && x.CouldCloseTo(@interface)))
- {
- try
+ if (exactMatches.Count > 1)
{
- services.TryAddTransient(@interface, type.MakeGenericType(@interface.GenericTypeArguments));
+ exactMatches.RemoveAll(m => !IsMatchingWithInterface(m, @interface));
}
- catch (Exception)
+
+ foreach (var type in exactMatches)
{
+ services.TryAddTransient(@interface, type);
}
}
- }
- private static bool CouldCloseTo(this Type openConcretion, Type closedInterface)
- {
- var openInterface = closedInterface.GetGenericTypeDefinition();
- var arguments = closedInterface.GenericTypeArguments;
-
- var concreteArguments = openConcretion.GenericTypeArguments;
- return arguments.Length == concreteArguments.Length && openConcretion.CanBeCastTo(openInterface);
+ if (!@interface.IsOpenGeneric())
+ {
+ AddConcretionsThatCouldBeClosed(@interface, concretions, services);
+ }
}
+ }
- private static bool CanBeCastTo(this Type pluggedType, Type pluginType)
+ private static bool IsMatchingWithInterface(Type handlerType, Type handlerInterface)
+ {
+ if (handlerType == null || handlerInterface == null)
{
- if (pluggedType == null) return false;
-
- if (pluggedType == pluginType) return true;
-
- return pluginType.GetTypeInfo().IsAssignableFrom(pluggedType.GetTypeInfo());
+ return false;
}
- public static bool IsOpenGeneric(this Type type)
+ if (handlerType.IsInterface)
{
- return type.GetTypeInfo().IsGenericTypeDefinition || type.GetTypeInfo().ContainsGenericParameters;
+ if (handlerType.GenericTypeArguments.SequenceEqual(handlerInterface.GenericTypeArguments))
+ {
+ return true;
+ }
}
-
- public static IEnumerable FindInterfacesThatClose(this Type pluggedType, Type templateType)
+ else
{
- return FindInterfacesThatClosesCore(pluggedType, templateType).Distinct();
+ return IsMatchingWithInterface(handlerType.GetInterface(handlerInterface.Name), handlerInterface);
}
- private static IEnumerable FindInterfacesThatClosesCore(Type pluggedType, Type templateType)
- {
- if (pluggedType == null) yield break;
-
- if (!pluggedType.IsConcrete()) yield break;
+ return false;
+ }
- if (templateType.GetTypeInfo().IsInterface)
+ private static void AddConcretionsThatCouldBeClosed(Type @interface, List concretions, IServiceCollection services)
+ {
+ foreach (var type in concretions
+ .Where(x => x.IsOpenGeneric() && x.CouldCloseTo(@interface)))
+ {
+ try
{
- foreach (
- var interfaceType in
- pluggedType.GetInterfaces()
- .Where(type => type.GetTypeInfo().IsGenericType && (type.GetGenericTypeDefinition() == templateType)))
- {
- yield return interfaceType;
- }
+ services.TryAddTransient(@interface, type.MakeGenericType(@interface.GenericTypeArguments));
}
- else if (pluggedType.GetTypeInfo().BaseType.GetTypeInfo().IsGenericType &&
- (pluggedType.GetTypeInfo().BaseType.GetGenericTypeDefinition() == templateType))
+ catch (Exception)
{
- yield return pluggedType.GetTypeInfo().BaseType;
}
+ }
+ }
+
+ private static bool CouldCloseTo(this Type openConcretion, Type closedInterface)
+ {
+ var openInterface = closedInterface.GetGenericTypeDefinition();
+ var arguments = closedInterface.GenericTypeArguments;
+
+ var concreteArguments = openConcretion.GenericTypeArguments;
+ return arguments.Length == concreteArguments.Length && openConcretion.CanBeCastTo(openInterface);
+ }
+
+ private static bool CanBeCastTo(this Type pluggedType, Type pluginType)
+ {
+ if (pluggedType == null) return false;
+
+ if (pluggedType == pluginType) return true;
+
+ return pluginType.GetTypeInfo().IsAssignableFrom(pluggedType.GetTypeInfo());
+ }
+
+ private static bool IsOpenGeneric(this Type type)
+ {
+ return type.GetTypeInfo().IsGenericTypeDefinition || type.GetTypeInfo().ContainsGenericParameters;
+ }
+
+ private static IEnumerable FindInterfacesThatClose(this Type pluggedType, Type templateType)
+ {
+ return FindInterfacesThatClosesCore(pluggedType, templateType).Distinct();
+ }
+
+ private static IEnumerable FindInterfacesThatClosesCore(Type pluggedType, Type templateType)
+ {
+ if (pluggedType == null) yield break;
- if (pluggedType.GetTypeInfo().BaseType == typeof(object)) yield break;
+ if (!pluggedType.IsConcrete()) yield break;
- foreach (var interfaceType in FindInterfacesThatClosesCore(pluggedType.GetTypeInfo().BaseType, templateType))
+ if (templateType.GetTypeInfo().IsInterface)
+ {
+ foreach (
+ var interfaceType in
+ pluggedType.GetInterfaces()
+ .Where(type => type.GetTypeInfo().IsGenericType && (type.GetGenericTypeDefinition() == templateType)))
{
yield return interfaceType;
}
}
-
- private static bool IsConcrete(this Type type)
+ else if (pluggedType.GetTypeInfo().BaseType.GetTypeInfo().IsGenericType &&
+ (pluggedType.GetTypeInfo().BaseType.GetGenericTypeDefinition() == templateType))
{
- return !type.GetTypeInfo().IsAbstract && !type.GetTypeInfo().IsInterface;
+ yield return pluggedType.GetTypeInfo().BaseType;
}
- private static void Fill(this IList list, T value)
+ if (pluggedType.GetTypeInfo().BaseType == typeof(object)) yield break;
+
+ foreach (var interfaceType in FindInterfacesThatClosesCore(pluggedType.GetTypeInfo().BaseType, templateType))
{
- if (list.Contains(value)) return;
- list.Add(value);
+ yield return interfaceType;
}
+ }
+
+ private static bool IsConcrete(this Type type)
+ {
+ return !type.GetTypeInfo().IsAbstract && !type.GetTypeInfo().IsInterface;
+ }
+
+ private static void Fill(this IList list, T value)
+ {
+ if (list.Contains(value)) return;
+ list.Add(value);
+ }
- public static void AddRequiredServices(IServiceCollection services, MediatRServiceConfiguration serviceConfiguration)
+ public static void AddRequiredServices(IServiceCollection services, MediatRServiceConfiguration serviceConfiguration)
+ {
+ // Use TryAdd, so any existing ServiceFactory/IMediator registration doesn't get overriden
+ services.TryAddTransient(p => p.GetRequiredService);
+ services.TryAdd(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));
+ services.TryAdd(new ServiceDescriptor(typeof(ISender), sp => sp.GetRequiredService(), serviceConfiguration.Lifetime));
+ services.TryAdd(new ServiceDescriptor(typeof(IPublisher), sp => sp.GetRequiredService(), serviceConfiguration.Lifetime));
+
+ // Use TryAddTransientExact (see below), we dó want to register our Pre/Post processor behavior, even if (a more concrete)
+ // registration for IPipelineBehavior<,> already exists. But only once.
+ services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
+ services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
+
+ if (serviceConfiguration.RequestExceptionActionProcessorStrategy == RequestExceptionActionProcessorStrategy.ApplyForUnhandledExceptions)
{
- // Use TryAdd, so any existing ServiceFactory/IMediator registration doesn't get overriden
- services.TryAddTransient(p => p.GetService);
- services.TryAdd(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));
- services.TryAdd(new ServiceDescriptor(typeof(ISender), sp => sp.GetService(), serviceConfiguration.Lifetime));
- services.TryAdd(new ServiceDescriptor(typeof(IPublisher), sp => sp.GetService(), serviceConfiguration.Lifetime));
-
- // Use TryAddTransientExact (see below), we dó want to register our Pre/Post processor behavior, even if (a more concrete)
- // registration for IPipelineBehavior<,> already exists. But only once.
- services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
- services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
-
- if (serviceConfiguration.RequestExceptionActionProcessorStrategy == RequestExceptionActionProcessorStrategy.ApplyForUnhandledExceptions)
- {
- services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionActionProcessorBehavior<,>));
- services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionProcessorBehavior<,>));
- }
- else
- {
- services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionProcessorBehavior<,>));
- services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionActionProcessorBehavior<,>));
- }
+ services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionActionProcessorBehavior<,>));
+ services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionProcessorBehavior<,>));
}
-
- ///
- /// Adds a new transient registration to the service collection only when no existing registration of the same service type and implementation type exists.
- /// In contrast to TryAddTransient, which only checks the service type.
- ///
- /// The service collection
- /// Service type
- /// Implementation type
- private static void TryAddTransientExact(this IServiceCollection services, Type serviceType, Type implementationType)
+ else
{
- if (services.Any(reg => reg.ServiceType == serviceType && reg.ImplementationType == implementationType))
- {
- return;
- }
+ services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionProcessorBehavior<,>));
+ services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionActionProcessorBehavior<,>));
+ }
+ }
- services.AddTransient(serviceType, implementationType);
+ ///
+ /// Adds a new transient registration to the service collection only when no existing registration of the same service type and implementation type exists.
+ /// In contrast to TryAddTransient, which only checks the service type.
+ ///
+ /// The service collection
+ /// Service type
+ /// Implementation type
+ private static void TryAddTransientExact(this IServiceCollection services, Type serviceType, Type implementationType)
+ {
+ if (services.Any(reg => reg.ServiceType == serviceType && reg.ImplementationType == implementationType))
+ {
+ return;
}
+
+ services.AddTransient(serviceType, implementationType);
}
}
\ No newline at end of file
diff --git a/src/MediatR.Extensions.Microsoft.DependencyInjection/RequestExceptionActionProcessorStrategy.cs b/src/MediatR.Extensions.Microsoft.DependencyInjection/RequestExceptionActionProcessorStrategy.cs
new file mode 100644
index 0000000..fa2c823
--- /dev/null
+++ b/src/MediatR.Extensions.Microsoft.DependencyInjection/RequestExceptionActionProcessorStrategy.cs
@@ -0,0 +1,7 @@
+namespace MediatR;
+
+public enum RequestExceptionActionProcessorStrategy
+{
+ ApplyForUnhandledExceptions,
+ ApplyForAllExceptions
+}
\ No newline at end of file
diff --git a/src/MediatR.Extensions.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs b/src/MediatR.Extensions.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs
index f57708d..69045d4 100644
--- a/src/MediatR.Extensions.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs
+++ b/src/MediatR.Extensions.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs
@@ -1,94 +1,93 @@
-namespace MediatR
-{
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using Pipeline;
- using Registration;
- using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using MediatR.Pipeline;
+using MediatR.Registration;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace MediatR;
+///
+/// Extensions to scan for MediatR handlers and registers them.
+/// - Scans for any handler interface implementations and registers them as
+/// - Scans for any and implementations and registers them as transient instances
+/// Registers and as transient instances
+/// After calling AddMediatR you can use the container to resolve an instance.
+/// This does not scan for any instances including and .
+/// To register behaviors, use the with the open generic or closed generic types.
+///
+public static class ServiceCollectionExtensions
+{
///
- /// Extensions to scan for MediatR handlers and registers them.
- /// - Scans for any handler interface implementations and registers them as
- /// - Scans for any and implementations and registers them as transient instances
- /// Registers and as transient instances
- /// After calling AddMediatR you can use the container to resolve an instance.
- /// This does not scan for any instances including and .
- /// To register behaviors, use the with the open generic or closed generic types.
+ /// Registers handlers and mediator types from the specified assemblies
///
- public static class ServiceCollectionExtensions
- {
- ///
- /// Registers handlers and mediator types from the specified assemblies
- ///
- /// Service collection
- /// Assemblies to scan
- /// Service collection
- public static IServiceCollection AddMediatR(this IServiceCollection services, params Assembly[] assemblies)
- => services.AddMediatR(assemblies, configuration: null);
+ /// Service collection
+ /// Assemblies to scan
+ /// Service collection
+ public static IServiceCollection AddMediatR(this IServiceCollection services, params Assembly[] assemblies)
+ => services.AddMediatR(assemblies, configuration: null);
- ///
- /// Registers handlers and mediator types from the specified assemblies
- ///
- /// Service collection
- /// Assemblies to scan
- /// The action used to configure the options
- /// Service collection
- public static IServiceCollection AddMediatR(this IServiceCollection services, Action configuration, params Assembly[] assemblies)
- => services.AddMediatR(assemblies, configuration);
+ ///
+ /// Registers handlers and mediator types from the specified assemblies
+ ///
+ /// Service collection
+ /// Assemblies to scan
+ /// The action used to configure the options
+ /// Service collection
+ public static IServiceCollection AddMediatR(this IServiceCollection services, Action? configuration, params Assembly[] assemblies)
+ => services.AddMediatR(assemblies, configuration);
- ///
- /// Registers handlers and mediator types from the specified assemblies
- ///
- /// Service collection
- /// Assemblies to scan
- /// The action used to configure the options
- /// Service collection
- public static IServiceCollection AddMediatR(this IServiceCollection services, IEnumerable assemblies, Action configuration)
+ ///
+ /// Registers handlers and mediator types from the specified assemblies
+ ///
+ /// Service collection
+ /// Assemblies to scan
+ /// The action used to configure the options
+ /// Service collection
+ public static IServiceCollection AddMediatR(this IServiceCollection services, IEnumerable assemblies, Action? configuration)
+ {
+ if (!assemblies.Any())
{
- if (!assemblies.Any())
- {
- throw new ArgumentException("No assemblies found to scan. Supply at least one assembly to scan for handlers.");
- }
- var serviceConfig = new MediatRServiceConfiguration();
+ throw new ArgumentException("No assemblies found to scan. Supply at least one assembly to scan for handlers.");
+ }
+ var serviceConfig = new MediatRServiceConfiguration();
- configuration?.Invoke(serviceConfig);
+ configuration?.Invoke(serviceConfig);
- ServiceRegistrar.AddRequiredServices(services, serviceConfig);
+ ServiceRegistrar.AddRequiredServices(services, serviceConfig);
- ServiceRegistrar.AddMediatRClasses(services, assemblies, serviceConfig);
+ ServiceRegistrar.AddMediatRClasses(services, assemblies, serviceConfig);
- return services;
- }
+ return services;
+ }
- ///
- /// Registers handlers and mediator types from the assemblies that contain the specified types
- ///
- ///
- ///
- /// Service collection
- public static IServiceCollection AddMediatR(this IServiceCollection services, params Type[] handlerAssemblyMarkerTypes)
- => services.AddMediatR(handlerAssemblyMarkerTypes, configuration: null);
+ ///
+ /// Registers handlers and mediator types from the assemblies that contain the specified types
+ ///
+ ///
+ ///
+ /// Service collection
+ public static IServiceCollection AddMediatR(this IServiceCollection services, params Type[] handlerAssemblyMarkerTypes)
+ => services.AddMediatR(handlerAssemblyMarkerTypes, configuration: null);
- ///
- /// Registers handlers and mediator types from the assemblies that contain the specified types
- ///
- ///
- ///
- /// The action used to configure the options
- /// Service collection
- public static IServiceCollection AddMediatR(this IServiceCollection services, Action configuration, params Type[] handlerAssemblyMarkerTypes)
- => services.AddMediatR(handlerAssemblyMarkerTypes, configuration);
+ ///
+ /// Registers handlers and mediator types from the assemblies that contain the specified types
+ ///
+ ///
+ ///
+ /// The action used to configure the options
+ /// Service collection
+ public static IServiceCollection AddMediatR(this IServiceCollection services, Action? configuration, params Type[] handlerAssemblyMarkerTypes)
+ => services.AddMediatR(handlerAssemblyMarkerTypes, configuration);
- ///
- /// Registers handlers and mediator types from the assemblies that contain the specified types
- ///
- ///
- ///
- /// The action used to configure the options
- /// Service collection
- public static IServiceCollection AddMediatR(this IServiceCollection services, IEnumerable handlerAssemblyMarkerTypes, Action configuration)
- => services.AddMediatR(handlerAssemblyMarkerTypes.Select(t => t.GetTypeInfo().Assembly), configuration);
- }
-}
+ ///
+ /// Registers handlers and mediator types from the assemblies that contain the specified types
+ ///
+ ///
+ ///
+ /// The action used to configure the options
+ /// Service collection
+ public static IServiceCollection AddMediatR(this IServiceCollection services, IEnumerable handlerAssemblyMarkerTypes, Action? configuration)
+ => services.AddMediatR(handlerAssemblyMarkerTypes.Select(t => t.GetTypeInfo().Assembly), configuration);
+}
\ No newline at end of file
diff --git a/src/TestApp/ConstrainedPingedHandler.cs b/src/TestApp/ConstrainedPingedHandler.cs
new file mode 100644
index 0000000..9ecf394
--- /dev/null
+++ b/src/TestApp/ConstrainedPingedHandler.cs
@@ -0,0 +1,22 @@
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using MediatR;
+
+namespace TestApp;
+
+public class ConstrainedPingedHandler : INotificationHandler
+ where TNotification : Pinged
+{
+ private readonly TextWriter _writer;
+
+ public ConstrainedPingedHandler(TextWriter writer)
+ {
+ _writer = writer;
+ }
+
+ public Task Handle(TNotification notification, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync("Got pinged constrained async.");
+ }
+}
diff --git a/src/TestApp/ConstrainedRequestPostProcessor.cs b/src/TestApp/ConstrainedRequestPostProcessor.cs
index 317f1c3..88d19ee 100644
--- a/src/TestApp/ConstrainedRequestPostProcessor.cs
+++ b/src/TestApp/ConstrainedRequestPostProcessor.cs
@@ -1,23 +1,24 @@
using System.IO;
+using System.Threading;
using System.Threading.Tasks;
+using MediatR;
using MediatR.Pipeline;
-namespace TestApp
+namespace TestApp;
+
+public class ConstrainedRequestPostProcessor
+ : IRequestPostProcessor
+ where TRequest : Ping, IRequest
{
- //public class ConstrainedRequestPostProcessor
- // : IRequestPostProcessor
- // where TRequest : Ping
- //{
- // private readonly TextWriter _writer;
+ private readonly TextWriter _writer;
- // public ConstrainedRequestPostProcessor(TextWriter writer)
- // {
- // _writer = writer;
- // }
+ public ConstrainedRequestPostProcessor(TextWriter writer)
+ {
+ _writer = writer;
+ }
- // public Task Process(TRequest request, TResponse response)
- // {
- // return _writer.WriteLineAsync("- All Done with Ping");
- // }
- //}
+ public Task Process(TRequest request, TResponse response, CancellationToken token)
+ {
+ return _writer.WriteLineAsync("- All Done with Ping");
+ }
}
\ No newline at end of file
diff --git a/src/TestApp/GenericHandler.cs b/src/TestApp/GenericHandler.cs
index e21b0d1..450a87c 100644
--- a/src/TestApp/GenericHandler.cs
+++ b/src/TestApp/GenericHandler.cs
@@ -2,22 +2,21 @@
using System.Threading.Tasks;
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+using System.IO;
+
+public class GenericHandler : INotificationHandler
{
- using System.IO;
+ private readonly TextWriter _writer;
- public class GenericHandler : INotificationHandler
+ public GenericHandler(TextWriter writer)
{
- private readonly TextWriter _writer;
-
- public GenericHandler(TextWriter writer)
- {
- _writer = writer;
- }
+ _writer = writer;
+ }
- public Task Handle(INotification notification, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync("Got notified.");
- }
+ public Task Handle(INotification notification, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync("Got notified.");
}
}
\ No newline at end of file
diff --git a/src/TestApp/GenericPipelineBehavior.cs b/src/TestApp/GenericPipelineBehavior.cs
index 25940d7..654aa24 100644
--- a/src/TestApp/GenericPipelineBehavior.cs
+++ b/src/TestApp/GenericPipelineBehavior.cs
@@ -3,23 +3,23 @@
using System.Threading.Tasks;
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+public class GenericPipelineBehavior : IPipelineBehavior
+ where TRequest: IRequest
{
- public class GenericPipelineBehavior : IPipelineBehavior
- {
- private readonly TextWriter _writer;
+ private readonly TextWriter _writer;
- public GenericPipelineBehavior(TextWriter writer)
- {
- _writer = writer;
- }
+ public GenericPipelineBehavior(TextWriter writer)
+ {
+ _writer = writer;
+ }
- public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next)
- {
- await _writer.WriteLineAsync("-- Handling Request");
- var response = await next();
- await _writer.WriteLineAsync("-- Finished Request");
- return response;
- }
+ public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next)
+ {
+ await _writer.WriteLineAsync("-- Handling Request");
+ var response = await next();
+ await _writer.WriteLineAsync("-- Finished Request");
+ return response;
}
-}
+}
\ No newline at end of file
diff --git a/src/TestApp/GenericRequestPostProcessor.cs b/src/TestApp/GenericRequestPostProcessor.cs
index ce7f9ee..d1271a4 100644
--- a/src/TestApp/GenericRequestPostProcessor.cs
+++ b/src/TestApp/GenericRequestPostProcessor.cs
@@ -1,22 +1,24 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+using MediatR;
using MediatR.Pipeline;
-namespace TestApp
+namespace TestApp;
+
+public class GenericRequestPostProcessor : IRequestPostProcessor
+ where TRequest : IRequest
+
{
- public class GenericRequestPostProcessor : IRequestPostProcessor
- {
- private readonly TextWriter _writer;
+ private readonly TextWriter _writer;
- public GenericRequestPostProcessor(TextWriter writer)
- {
- _writer = writer;
- }
+ public GenericRequestPostProcessor(TextWriter writer)
+ {
+ _writer = writer;
+ }
- public Task Process(TRequest request, TResponse response, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync("- All Done");
- }
+ public Task Process(TRequest request, TResponse response, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync("- All Done");
}
}
\ No newline at end of file
diff --git a/src/TestApp/GenericRequestPreProcessor.cs b/src/TestApp/GenericRequestPreProcessor.cs
index 18f4db5..36ca8ca 100644
--- a/src/TestApp/GenericRequestPreProcessor.cs
+++ b/src/TestApp/GenericRequestPreProcessor.cs
@@ -3,20 +3,19 @@
using System.Threading.Tasks;
using MediatR.Pipeline;
-namespace TestApp
+namespace TestApp;
+
+public class GenericRequestPreProcessor : IRequestPreProcessor where TRequest : notnull
{
- public class GenericRequestPreProcessor : IRequestPreProcessor
- {
- private readonly TextWriter _writer;
+ private readonly TextWriter _writer;
- public GenericRequestPreProcessor(TextWriter writer)
- {
- _writer = writer;
- }
+ public GenericRequestPreProcessor(TextWriter writer)
+ {
+ _writer = writer;
+ }
- public Task Process(TRequest request, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync("- Starting Up");
- }
+ public Task Process(TRequest request, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync("- Starting Up");
}
}
\ No newline at end of file
diff --git a/src/TestApp/Jing.cs b/src/TestApp/Jing.cs
index 9c5f5ae..5bc4f4e 100644
--- a/src/TestApp/Jing.cs
+++ b/src/TestApp/Jing.cs
@@ -5,10 +5,9 @@
using System.Threading.Tasks;
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+public class Jing : IRequest
{
- public class Jing : IRequest
- {
- public string Message { get; set; }
- }
-}
+ public string? Message { get; set; }
+}
\ No newline at end of file
diff --git a/src/TestApp/JingHandler.cs b/src/TestApp/JingHandler.cs
index e24d6a4..7c172f2 100644
--- a/src/TestApp/JingHandler.cs
+++ b/src/TestApp/JingHandler.cs
@@ -3,20 +3,19 @@
using System.Threading.Tasks;
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+public class JingHandler : AsyncRequestHandler
{
- public class JingHandler : AsyncRequestHandler
- {
- private readonly TextWriter _writer;
+ private readonly TextWriter _writer;
- public JingHandler(TextWriter writer)
- {
- _writer = writer;
- }
+ public JingHandler(TextWriter writer)
+ {
+ _writer = writer;
+ }
- protected override Task Handle(Jing request, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync($"--- Handled Jing: {request.Message}, no Jong");
- }
+ protected override Task Handle(Jing request, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync($"--- Handled Jing: {request.Message}, no Jong");
}
-}
+}
\ No newline at end of file
diff --git a/src/TestApp/Ping.cs b/src/TestApp/Ping.cs
index 3b9a69c..99a3c18 100644
--- a/src/TestApp/Ping.cs
+++ b/src/TestApp/Ping.cs
@@ -1,10 +1,9 @@
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+public class Ping : IRequest
{
- public class Ping : IRequest
- {
- public string Message { get; set; }
- public bool Throw { get; set; }
- }
+ public string? Message { get; set; }
+ public bool Throw { get; set; }
}
\ No newline at end of file
diff --git a/src/TestApp/PingHandler.cs b/src/TestApp/PingHandler.cs
index 529c2f4..359f1b3 100644
--- a/src/TestApp/PingHandler.cs
+++ b/src/TestApp/PingHandler.cs
@@ -3,29 +3,28 @@
using System.Threading;
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+using System.Threading.Tasks;
+
+public class PingHandler : IRequestHandler
{
- using System.Threading.Tasks;
+ private readonly TextWriter _writer;
- public class PingHandler : IRequestHandler
+ public PingHandler(TextWriter writer)
{
- private readonly TextWriter _writer;
+ _writer = writer;
+ }
- public PingHandler(TextWriter writer)
- {
- _writer = writer;
- }
+ public async Task Handle(Ping request, CancellationToken cancellationToken)
+ {
+ await _writer.WriteLineAsync($"--- Handled Ping: {request.Message}");
- public async Task Handle(Ping request, CancellationToken cancellationToken)
+ if (request.Throw)
{
- await _writer.WriteLineAsync($"--- Handled Ping: {request.Message}");
-
- if (request.Throw)
- {
- throw new ApplicationException("Requested to throw");
- }
-
- return new Pong { Message = request.Message + " Pong" };
+ throw new ApplicationException("Requested to throw");
}
+
+ return new Pong { Message = request.Message + " Pong" };
}
}
\ No newline at end of file
diff --git a/src/TestApp/PingPongExceptionHandlers.cs b/src/TestApp/PingPongExceptionHandlers.cs
index e9b98a9..4ded800 100644
--- a/src/TestApp/PingPongExceptionHandlers.cs
+++ b/src/TestApp/PingPongExceptionHandlers.cs
@@ -4,37 +4,34 @@
using System.Threading.Tasks;
using MediatR.Pipeline;
-namespace TestApp
+namespace TestApp;
+
+public class PingPongExceptionHandlerForType : IRequestExceptionHandler
{
- public class PingPongExceptionHandlerForType : IRequestExceptionHandler
+ public Task Handle(Ping request, ApplicationException exception, RequestExceptionHandlerState state, CancellationToken cancellationToken)
{
- public Task Handle(Ping request, ApplicationException exception, RequestExceptionHandlerState state, CancellationToken cancellationToken)
- {
- state.SetHandled(new Pong { Message = exception.Message + " Handled by Type" });
+ state.SetHandled(new Pong { Message = exception.Message + " Handled by Type" });
- return Task.CompletedTask;
- }
+ return Task.CompletedTask;
}
+}
- public class PingPongExceptionActionForType1 : IRequestExceptionAction
- {
- private readonly TextWriter _output;
-
- public PingPongExceptionActionForType1(TextWriter output) => _output = output;
-
- public Task Execute(Ping request, ApplicationException exception, CancellationToken cancellationToken)
- => _output.WriteLineAsync("Logging exception 1");
- }
+public class PingPongExceptionActionForType1 : IRequestExceptionAction
+{
+ private readonly TextWriter _output;
- public class PingPongExceptionActionForType2 : IRequestExceptionAction
- {
- private readonly TextWriter _output;
+ public PingPongExceptionActionForType1(TextWriter output) => _output = output;
- public PingPongExceptionActionForType2(TextWriter output) => _output = output;
+ public Task Execute(Ping request, ApplicationException exception, CancellationToken cancellationToken)
+ => _output.WriteLineAsync("Logging exception 1");
+}
- public Task Execute(Ping request, ApplicationException exception, CancellationToken cancellationToken)
- => _output.WriteLineAsync("Logging exception 2");
- }
+public class PingPongExceptionActionForType2 : IRequestExceptionAction
+{
+ private readonly TextWriter _output;
+ public PingPongExceptionActionForType2(TextWriter output) => _output = output;
+ public Task Execute(Ping request, ApplicationException exception, CancellationToken cancellationToken)
+ => _output.WriteLineAsync("Logging exception 2");
}
\ No newline at end of file
diff --git a/src/TestApp/Pinged.cs b/src/TestApp/Pinged.cs
index 663fe1d..6073628 100644
--- a/src/TestApp/Pinged.cs
+++ b/src/TestApp/Pinged.cs
@@ -1,9 +1,8 @@
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+public class Pinged : INotification
{
- public class Pinged : INotification
- {
- }
}
\ No newline at end of file
diff --git a/src/TestApp/PingedHandler.cs b/src/TestApp/PingedHandler.cs
index b653f00..f0d849e 100644
--- a/src/TestApp/PingedHandler.cs
+++ b/src/TestApp/PingedHandler.cs
@@ -1,69 +1,68 @@
using System.Threading;
using MediatR;
-namespace TestApp
-{
- using System.IO;
- using System.Threading.Tasks;
+namespace TestApp;
- public class PingedHandler : INotificationHandler
- {
- private readonly TextWriter _writer;
+using System.IO;
+using System.Threading.Tasks;
- public PingedHandler(TextWriter writer)
- {
- _writer = writer;
- }
+public class PingedHandler : INotificationHandler
+{
+ private readonly TextWriter _writer;
- public Task Handle(Pinged notification, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync("Got pinged async.");
- }
+ public PingedHandler(TextWriter writer)
+ {
+ _writer = writer;
}
- public class PongedHandler : INotificationHandler
+ public Task Handle(Pinged notification, CancellationToken cancellationToken)
{
- private readonly TextWriter _writer;
+ return _writer.WriteLineAsync("Got pinged async.");
+ }
+}
- public PongedHandler(TextWriter writer)
- {
- _writer = writer;
- }
+public class PongedHandler : INotificationHandler
+{
+ private readonly TextWriter _writer;
- public Task Handle(Ponged notification, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync("Got ponged async.");
- }
+ public PongedHandler(TextWriter writer)
+ {
+ _writer = writer;
}
- //public class ConstrainedPingedHandler : INotificationHandler
- // where TNotification : Pinged
- //{
- // private readonly TextWriter _writer;
+ public Task Handle(Ponged notification, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync("Got ponged async.");
+ }
+}
- // public ConstrainedPingedHandler(TextWriter writer)
- // {
- // _writer = writer;
- // }
+//public class ConstrainedPingedHandler : INotificationHandler
+// where TNotification : Pinged
+//{
+// private readonly TextWriter _writer;
- // public Task Handle(TNotification notification, CancellationToken cancellationToken)
- // {
- // return _writer.WriteLineAsync("Got pinged constrained async.");
- // }
- //}
+// public ConstrainedPingedHandler(TextWriter writer)
+// {
+// _writer = writer;
+// }
- public class PingedAlsoHandler : INotificationHandler
- {
- private readonly TextWriter _writer;
+// public Task Handle(TNotification notification, CancellationToken cancellationToken)
+// {
+// return _writer.WriteLineAsync("Got pinged constrained async.");
+// }
+//}
- public PingedAlsoHandler(TextWriter writer)
- {
- _writer = writer;
- }
+public class PingedAlsoHandler : INotificationHandler
+{
+ private readonly TextWriter _writer;
- public Task Handle(Pinged notification, CancellationToken cancellationToken)
- {
- return _writer.WriteLineAsync("Got pinged also async.");
- }
+ public PingedAlsoHandler(TextWriter writer)
+ {
+ _writer = writer;
+ }
+
+ public Task Handle(Pinged notification, CancellationToken cancellationToken)
+ {
+ return _writer.WriteLineAsync("Got pinged also async.");
}
}
\ No newline at end of file
diff --git a/src/TestApp/Pong.cs b/src/TestApp/Pong.cs
index ec24766..11e6122 100644
--- a/src/TestApp/Pong.cs
+++ b/src/TestApp/Pong.cs
@@ -1,7 +1,6 @@
-namespace TestApp
+namespace TestApp;
+
+public class Pong
{
- public class Pong
- {
- public string Message { get; set; }
- }
+ public string? Message { get; set; }
}
\ No newline at end of file
diff --git a/src/TestApp/Ponged.cs b/src/TestApp/Ponged.cs
index d51725f..0acb5db 100644
--- a/src/TestApp/Ponged.cs
+++ b/src/TestApp/Ponged.cs
@@ -1,9 +1,8 @@
using MediatR;
-namespace TestApp
+namespace TestApp;
+
+public class Ponged : INotification
{
- public class Ponged : INotification
- {
- }
}
\ No newline at end of file
diff --git a/src/TestApp/Program.cs b/src/TestApp/Program.cs
index d97420a..026d704 100644
--- a/src/TestApp/Program.cs
+++ b/src/TestApp/Program.cs
@@ -6,45 +6,42 @@
using System.Threading.Tasks;
using MediatR.Pipeline;
-namespace TestApp
-{
+namespace TestApp;
- public class Program
+public class Program
+{
+ public static Task Main(string[] args)
{
- public static Task Main(string[] args)
- {
- var writer = new WrappingWriter(Console.Out);
- var mediator = BuildMediator(writer);
- return Runner.Run(mediator, writer, "ASP.NET Core DI");
- }
+ var writer = new WrappingWriter(Console.Out);
+ var mediator = BuildMediator(writer);
+ return Runner.Run(mediator, writer, "ASP.NET Core DI");
+ }
- private static IMediator BuildMediator(WrappingWriter writer)
- {
- var services = new ServiceCollection();
+ private static IMediator BuildMediator(WrappingWriter writer)
+ {
+ var services = new ServiceCollection();
- services.AddScoped(p => p.GetService);
+ services.AddScoped(p => p.GetRequiredService);
- services.AddSingleton(writer);
+ services.AddSingleton(writer);
- //Pipeline
+ //Pipeline
- //This causes a type load exception. https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection/issues/12
- //services.AddScoped(typeof(IRequestPostProcessor<,>), typeof(ConstrainedRequestPostProcessor<,>));
- //services.AddScoped(typeof(INotificationHandler<>), typeof(ConstrainedPingedHandler<>));
+ //This causes a type load exception. https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection/issues/12
+ services.AddScoped(typeof(IRequestPostProcessor<,>), typeof(ConstrainedRequestPostProcessor<,>));
+ services.AddScoped(typeof(INotificationHandler<>), typeof(ConstrainedPingedHandler<>));
- services.AddMediatR(typeof(Ping));
+ services.AddMediatR(typeof(Ping));
- services.AddScoped(typeof(IPipelineBehavior<,>), typeof(GenericPipelineBehavior<,>));
+ services.AddScoped(typeof(IPipelineBehavior<,>), typeof(GenericPipelineBehavior<,>));
- foreach (var service in services)
- {
- Console.WriteLine(service.ServiceType + " - " + service.ImplementationType);
- }
+ foreach (var service in services)
+ {
+ Console.WriteLine(service.ServiceType + " - " + service.ImplementationType);
+ }
- var provider = services.BuildServiceProvider();
+ var provider = services.BuildServiceProvider();
- return provider.GetRequiredService();
- }
+ return provider.GetRequiredService();
}
-
-}
+}
\ No newline at end of file
diff --git a/src/TestApp/Runner.cs b/src/TestApp/Runner.cs
index e0f4f55..e37a2b1 100644
--- a/src/TestApp/Runner.cs
+++ b/src/TestApp/Runner.cs
@@ -3,130 +3,128 @@
using System.Text;
using MediatR;
-namespace TestApp
-{
- using System.IO;
- using System.Threading.Tasks;
+namespace TestApp;
- public static class Runner
- {
- public static async Task Run(IMediator mediator, WrappingWriter writer, string projectName)
- {
- await writer.WriteLineAsync("===============");
- await writer.WriteLineAsync(projectName);
- await writer.WriteLineAsync("===============");
-
- await writer.WriteLineAsync("Sending Ping...");
- var pong = await mediator.Send(new Ping { Message = "Ping" });
- await writer.WriteLineAsync("Received: " + pong.Message);
-
- await writer.WriteLineAsync("Publishing Pinged...");
- await mediator.Publish(new Pinged());
-
- await writer.WriteLineAsync("Publishing Ponged...");
- var failedPong = false;
- try
- {
- await mediator.Publish(new Ponged());
- }
- catch (Exception e)
- {
- failedPong = true;
- await writer.WriteLineAsync(e.ToString());
- }
-
- bool failedJing = false;
- await writer.WriteLineAsync("Sending Jing...");
- try
- {
- await mediator.Send(new Jing { Message = "Jing" });
- }
- catch (Exception e)
- {
- failedJing = true;
- await writer.WriteLineAsync(e.ToString());
- }
-
- await writer.WriteLineAsync("---------------");
- var contents = writer.Contents;
- var order = new[] {
- contents.IndexOf("- Starting Up", StringComparison.OrdinalIgnoreCase),
- contents.IndexOf("-- Handling Request", StringComparison.OrdinalIgnoreCase),
- contents.IndexOf("--- Handled Ping", StringComparison.OrdinalIgnoreCase),
- contents.IndexOf("-- Finished Request", StringComparison.OrdinalIgnoreCase),
- contents.IndexOf("- All Done", StringComparison.OrdinalIgnoreCase),
- contents.IndexOf("- All Done with Ping", StringComparison.OrdinalIgnoreCase),
- };
-
- var results = new RunResults
- {
- RequestHandlers = contents.Contains("--- Handled Ping:"),
- VoidRequestsHandlers = contents.Contains("--- Handled Jing:"),
- PipelineBehaviors = contents.Contains("-- Handling Request"),
- RequestPreProcessors = contents.Contains("- Starting Up"),
- RequestPostProcessors = contents.Contains("- All Done"),
- ConstrainedGenericBehaviors = contents.Contains("- All Done with Ping") && !failedJing,
- OrderedPipelineBehaviors = order.SequenceEqual(order.OrderBy(i => i)),
- NotificationHandler = contents.Contains("Got pinged async"),
- MultipleNotificationHandlers = contents.Contains("Got pinged async") && contents.Contains("Got pinged also async"),
- ConstrainedGenericNotificationHandler = contents.Contains("Got pinged constrained async") && !failedPong,
- CovariantNotificationHandler = contents.Contains("Got notified")
- };
-
- await writer.WriteLineAsync($"Request Handler...................{(results.RequestHandlers ? "Y" : "N")}");
- await writer.WriteLineAsync($"Void Request Handler..............{(results.VoidRequestsHandlers ? "Y" : "N")}");
- await writer.WriteLineAsync($"Pipeline Behavior.................{(results.PipelineBehaviors ? "Y" : "N")}");
- await writer.WriteLineAsync($"Pre-Processor.....................{(results.RequestPreProcessors ? "Y" : "N")}");
- await writer.WriteLineAsync($"Post-Processor....................{(results.RequestPostProcessors ? "Y" : "N")}");
- await writer.WriteLineAsync($"Constrained Post-Processor........{(results.ConstrainedGenericBehaviors ? "Y" : "N")}");
- await writer.WriteLineAsync($"Ordered Behaviors.................{(results.OrderedPipelineBehaviors ? "Y" : "N")}");
- await writer.WriteLineAsync($"Notification Handler..............{(results.NotificationHandler ? "Y" : "N")}");
- await writer.WriteLineAsync($"Notification Handlers.............{(results.MultipleNotificationHandlers ? "Y" : "N")}");
- await writer.WriteLineAsync($"Constrained Notification Handler..{(results.ConstrainedGenericNotificationHandler ? "Y" : "N")}");
- await writer.WriteLineAsync($"Covariant Notification Handler....{(results.CovariantNotificationHandler ? "Y" : "N")}");
- }
- }
+using System.IO;
+using System.Threading.Tasks;
- public class RunResults
+public static class Runner
+{
+ public static async Task Run(IMediator mediator, WrappingWriter writer, string projectName)
{
- public bool RequestHandlers { get; set; }
- public bool VoidRequestsHandlers { get; set; }
- public bool PipelineBehaviors { get; set; }
- public bool RequestPreProcessors { get; set; }
- public bool RequestPostProcessors { get; set; }
- public bool OrderedPipelineBehaviors { get; set; }
- public bool ConstrainedGenericBehaviors { get; set; }
- public bool NotificationHandler { get; set; }
- public bool MultipleNotificationHandlers { get; set; }
- public bool CovariantNotificationHandler { get; set; }
- public bool ConstrainedGenericNotificationHandler { get; set; }
- }
+ await writer.WriteLineAsync("===============");
+ await writer.WriteLineAsync(projectName);
+ await writer.WriteLineAsync("===============");
- public class WrappingWriter : TextWriter
- {
- private readonly TextWriter _innerWriter;
- private readonly StringBuilder _stringWriter = new StringBuilder();
+ await writer.WriteLineAsync("Sending Ping...");
+ var pong = await mediator.Send(new Ping { Message = "Ping" });
+ await writer.WriteLineAsync("Received: " + pong.Message);
+
+ await writer.WriteLineAsync("Publishing Pinged...");
+ await mediator.Publish(new Pinged());
- public WrappingWriter(TextWriter innerWriter)
+ await writer.WriteLineAsync("Publishing Ponged...");
+ var failedPong = false;
+ try
{
- _innerWriter = innerWriter;
+ await mediator.Publish(new Ponged());
}
-
- public override void Write(char value)
+ catch (Exception e)
{
- _stringWriter.Append(value);
- _innerWriter.Write(value);
+ failedPong = true;
+ await writer.WriteLineAsync(e.ToString());
}
- public override Task WriteLineAsync(string value)
+ bool failedJing = false;
+ await writer.WriteLineAsync("Sending Jing...");
+ try
{
- _stringWriter.AppendLine(value);
- return _innerWriter.WriteLineAsync(value);
+ await mediator.Send(new Jing { Message = "Jing" });
+ }
+ catch (Exception e)
+ {
+ failedJing = true;
+ await writer.WriteLineAsync(e.ToString());
}
- public override Encoding Encoding => _innerWriter.Encoding;
+ await writer.WriteLineAsync("---------------");
+ var contents = writer.Contents;
+ var order = new[] {
+ contents.IndexOf("- Starting Up", StringComparison.OrdinalIgnoreCase),
+ contents.IndexOf("-- Handling Request", StringComparison.OrdinalIgnoreCase),
+ contents.IndexOf("--- Handled Ping", StringComparison.OrdinalIgnoreCase),
+ contents.IndexOf("-- Finished Request", StringComparison.OrdinalIgnoreCase),
+ contents.IndexOf("- All Done", StringComparison.OrdinalIgnoreCase),
+ contents.IndexOf("- All Done with Ping", StringComparison.OrdinalIgnoreCase),
+ };
+
+ var results = new RunResults
+ {
+ RequestHandlers = contents.Contains("--- Handled Ping:"),
+ VoidRequestsHandlers = contents.Contains("--- Handled Jing:"),
+ PipelineBehaviors = contents.Contains("-- Handling Request"),
+ RequestPreProcessors = contents.Contains("- Starting Up"),
+ RequestPostProcessors = contents.Contains("- All Done"),
+ ConstrainedGenericBehaviors = contents.Contains("- All Done with Ping") && !failedJing,
+ OrderedPipelineBehaviors = order.SequenceEqual(order.OrderBy(i => i)),
+ NotificationHandler = contents.Contains("Got pinged async"),
+ MultipleNotificationHandlers = contents.Contains("Got pinged async") && contents.Contains("Got pinged also async"),
+ ConstrainedGenericNotificationHandler = contents.Contains("Got pinged constrained async") && !failedPong,
+ CovariantNotificationHandler = contents.Contains("Got notified")
+ };
+
+ await writer.WriteLineAsync($"Request Handler...................{(results.RequestHandlers ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Void Request Handler..............{(results.VoidRequestsHandlers ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Pipeline Behavior.................{(results.PipelineBehaviors ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Pre-Processor.....................{(results.RequestPreProcessors ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Post-Processor....................{(results.RequestPostProcessors ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Constrained Post-Processor........{(results.ConstrainedGenericBehaviors ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Ordered Behaviors.................{(results.OrderedPipelineBehaviors ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Notification Handler..............{(results.NotificationHandler ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Notification Handlers.............{(results.MultipleNotificationHandlers ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Constrained Notification Handler..{(results.ConstrainedGenericNotificationHandler ? "Y" : "N")}");
+ await writer.WriteLineAsync($"Covariant Notification Handler....{(results.CovariantNotificationHandler ? "Y" : "N")}");
+ }
+}
+
+public class RunResults
+{
+ public bool RequestHandlers { get; init; }
+ public bool VoidRequestsHandlers { get; init; }
+ public bool PipelineBehaviors { get; init; }
+ public bool RequestPreProcessors { get; init; }
+ public bool RequestPostProcessors { get; init; }
+ public bool OrderedPipelineBehaviors { get; init; }
+ public bool ConstrainedGenericBehaviors { get; init; }
+ public bool NotificationHandler { get; init; }
+ public bool MultipleNotificationHandlers { get; init; }
+ public bool CovariantNotificationHandler { get; init; }
+ public bool ConstrainedGenericNotificationHandler { get; init; }
+}
+
+public class WrappingWriter : TextWriter
+{
+ private readonly TextWriter _innerWriter;
+ private readonly StringBuilder _stringWriter = new();
+
+ public WrappingWriter(TextWriter innerWriter)
+ {
+ _innerWriter = innerWriter;
+ }
+
+ public override void Write(char value)
+ {
+ _stringWriter.Append(value);
+ _innerWriter.Write(value);
+ }
- public string Contents => _stringWriter.ToString();
+ public override Task WriteLineAsync(string? value)
+ {
+ _stringWriter.AppendLine(value);
+ return _innerWriter.WriteLineAsync(value);
}
+ public override Encoding Encoding => _innerWriter.Encoding;
+
+ public string Contents => _stringWriter.ToString();
}
\ No newline at end of file
diff --git a/src/TestApp/TestApp.csproj b/src/TestApp/TestApp.csproj
index 00243b7..2dd5576 100644
--- a/src/TestApp/TestApp.csproj
+++ b/src/TestApp/TestApp.csproj
@@ -1,7 +1,7 @@
- netcoreapp3.1
+ net6.0
Exe
@@ -10,11 +10,7 @@
-
-
-
-
-
+
diff --git a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/AssemblyResolutionTests.cs b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/AssemblyResolutionTests.cs
index b5a352d..520c921 100644
--- a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/AssemblyResolutionTests.cs
+++ b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/AssemblyResolutionTests.cs
@@ -1,57 +1,62 @@
using Microsoft.Extensions.DependencyInjection;
-namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests
+namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests;
+
+using System;
+using System.Linq;
+using System.Reflection;
+using Shouldly;
+using Xunit;
+
+public class AssemblyResolutionTests
{
- using System;
- using System.Linq;
- using System.Reflection;
- using Shouldly;
- using Xunit;
+ private readonly IServiceProvider _provider;
+
+ public AssemblyResolutionTests()
+ {
+ IServiceCollection services = new ServiceCollection();
+ services.AddSingleton(new Logger());
+ services.AddMediatR(typeof(Ping).GetTypeInfo().Assembly);
+ _provider = services.BuildServiceProvider();
+ }
+
+ [Fact]
+ public void ShouldResolveMediator()
+ {
+ _provider.GetService().ShouldNotBeNull();
+ }
+
+ [Fact]
+ public void ShouldResolveRequestHandler()
+ {
+ _provider.GetService>().ShouldNotBeNull();
+ }
- public class AssemblyResolutionTests
+ [Fact]
+ public void ShouldResolveInternalHandler()
{
- private readonly IServiceProvider _provider;
-
- public AssemblyResolutionTests()
- {
- IServiceCollection services = new ServiceCollection();
- services.AddSingleton(new Logger());
- services.AddMediatR(typeof(Ping).GetTypeInfo().Assembly);
- _provider = services.BuildServiceProvider();
- }
-
- [Fact]
- public void ShouldResolveMediator()
- {
- _provider.GetService().ShouldNotBeNull();
- }
-
- [Fact]
- public void ShouldResolveRequestHandler()
- {
- _provider.GetService>().ShouldNotBeNull();
- }
-
- [Fact]
- public void ShouldResolveInternalHandler()
- {
- _provider.GetService>().ShouldNotBeNull();
- }
-
- [Fact]
- public void ShouldResolveNotificationHandlers()
- {
- _provider.GetServices>().Count().ShouldBe(3);
- }
-
- [Fact]
- public void ShouldRequireAtLeastOneAssembly()
- {
- var services = new ServiceCollection();
-
- Action registration = () => services.AddMediatR(new Type[0]);
-
- registration.ShouldThrow();
- }
+ _provider.GetService>().ShouldNotBeNull();
+ }
+
+ [Fact]
+ public void ShouldResolveNotificationHandlers()
+ {
+ _provider.GetServices>().Count().ShouldBe(3);
+ }
+
+ [Fact]
+ public void ShouldResolveStreamHandlers()
+ {
+ _provider.GetService>().ShouldNotBeNull();
+ }
+
+ [Fact]
+ public void ShouldRequireAtLeastOneAssembly()
+ {
+ var services = new ServiceCollection();
+
+ Action registration = () => services.AddMediatR(new Type[0]);
+
+ registration.ShouldThrow();
}
}
\ No newline at end of file
diff --git a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/CustomMediatorTests.cs b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/CustomMediatorTests.cs
index e1196d8..7859afd 100644
--- a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/CustomMediatorTests.cs
+++ b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/CustomMediatorTests.cs
@@ -1,56 +1,55 @@
using Microsoft.Extensions.DependencyInjection;
-namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests
+namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests;
+
+using System;
+using System.Linq;
+using Shouldly;
+using Xunit;
+
+public class CustomMediatorTests
{
- using System;
- using System.Linq;
- using Shouldly;
- using Xunit;
+ private readonly IServiceProvider _provider;
+
+ public CustomMediatorTests()
+ {
+ IServiceCollection services = new ServiceCollection();
+ services.AddSingleton(new Logger());
+ services.AddMediatR(cfg => cfg.Using(), typeof(CustomMediatorTests));
+ _provider = services.BuildServiceProvider();
+ }
+
+ [Fact]
+ public void ShouldResolveMediator()
+ {
+ _provider.GetService().ShouldNotBeNull();
+ _provider.GetRequiredService().GetType().ShouldBe(typeof(MyCustomMediator));
+ }
+
+ [Fact]
+ public void ShouldResolveRequestHandler()
+ {
+ _provider.GetService>().ShouldNotBeNull();
+ }
+
+ [Fact]
+ public void ShouldResolveNotificationHandlers()
+ {
+ _provider.GetServices>().Count().ShouldBe(3);
+ }
- public class CustomMediatorTests
+ [Fact]
+ public void Can_Call_AddMediatr_multiple_times()
{
- private readonly IServiceProvider _provider;
-
- public CustomMediatorTests()
- {
- IServiceCollection services = new ServiceCollection();
- services.AddSingleton(new Logger());
- services.AddMediatR(cfg => cfg.Using(), typeof(CustomMediatorTests));
- _provider = services.BuildServiceProvider();
- }
-
- [Fact]
- public void ShouldResolveMediator()
- {
- _provider.GetService().ShouldNotBeNull();
- _provider.GetService().GetType().ShouldBe(typeof(MyCustomMediator));
- }
-
- [Fact]
- public void ShouldResolveRequestHandler()
- {
- _provider.GetService>().ShouldNotBeNull();
- }
-
- [Fact]
- public void ShouldResolveNotificationHandlers()
- {
- _provider.GetServices>().Count().ShouldBe(3);
- }
-
- [Fact]
- public void Can_Call_AddMediatr_multiple_times()
- {
- IServiceCollection services = new ServiceCollection();
- services.AddSingleton(new Logger());
- services.AddMediatR(cfg => cfg.Using(), typeof(CustomMediatorTests));
+ IServiceCollection services = new ServiceCollection();
+ services.AddSingleton(new Logger());
+ services.AddMediatR(cfg => cfg.Using(), typeof(CustomMediatorTests));
- // Call AddMediatr again, this should NOT override our custom mediatr (With MS DI, last registration wins)
- services.AddMediatR(typeof(CustomMediatorTests));
+ // Call AddMediatr again, this should NOT override our custom mediatr (With MS DI, last registration wins)
+ services.AddMediatR(typeof(CustomMediatorTests));
- var provider = services.BuildServiceProvider();
- var mediator = provider.GetRequiredService();
- mediator.GetType().ShouldBe(typeof(MyCustomMediator));
- }
+ var provider = services.BuildServiceProvider();
+ var mediator = provider.GetRequiredService();
+ mediator.GetType().ShouldBe(typeof(MyCustomMediator));
}
}
\ No newline at end of file
diff --git a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DerivingRequestsTests.cs b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DerivingRequestsTests.cs
index 37404ea..6ff2f26 100644
--- a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DerivingRequestsTests.cs
+++ b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DerivingRequestsTests.cs
@@ -4,34 +4,33 @@
using Shouldly;
using Xunit;
-namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests
+namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests;
+
+public class DerivingRequestsTests
{
- public class DerivingRequestsTests
- {
- private readonly IServiceProvider _provider;
- private readonly IMediator _mediator;
+ private readonly IServiceProvider _provider;
+ private readonly IMediator _mediator;
- public DerivingRequestsTests()
- {
- IServiceCollection services = new ServiceCollection();
- services.AddSingleton(new Logger());
- services.AddMediatR(typeof(Ping));
- _provider = services.BuildServiceProvider();
- _mediator = _provider.GetRequiredService();
- }
+ public DerivingRequestsTests()
+ {
+ IServiceCollection services = new ServiceCollection();
+ services.AddSingleton(new Logger());
+ services.AddMediatR(typeof(Ping));
+ _provider = services.BuildServiceProvider();
+ _mediator = _provider.GetRequiredService();
+ }
- [Fact]
- public async Task ShouldReturnPingPong()
- {
- Pong pong = await _mediator.Send(new Ping() { Message = "Ping" });
- pong.Message.ShouldBe("Ping Pong");
- }
+ [Fact]
+ public async Task ShouldReturnPingPong()
+ {
+ Pong pong = await _mediator.Send(new Ping() { Message = "Ping" });
+ pong.Message.ShouldBe("Ping Pong");
+ }
- [Fact]
- public async Task ShouldReturnDerivedPingPong()
- {
- Pong pong = await _mediator.Send(new DerivedPing() { Message = "Ping" });
- pong.Message.ShouldBe("DerivedPing Pong");
- }
+ [Fact]
+ public async Task ShouldReturnDerivedPingPong()
+ {
+ Pong pong = await _mediator.Send(new DerivedPing() { Message = "Ping" });
+ pong.Message.ShouldBe("DerivedPing Pong");
}
-}
+}
\ No newline at end of file
diff --git a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DuplicateAssemblyResolutionTests.cs b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DuplicateAssemblyResolutionTests.cs
index 0da3fe5..684a709 100644
--- a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DuplicateAssemblyResolutionTests.cs
+++ b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/DuplicateAssemblyResolutionTests.cs
@@ -1,28 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
-namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests
+namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests;
+
+using System;
+using System.Linq;
+using Shouldly;
+using Xunit;
+
+public class DuplicateAssemblyResolutionTests
{
- using System;
- using System.Linq;
- using Shouldly;
- using Xunit;
+ private readonly IServiceProvider _provider;
- public class DuplicateAssemblyResolutionTests
+ public DuplicateAssemblyResolutionTests()
{
- private readonly IServiceProvider _provider;
-
- public DuplicateAssemblyResolutionTests()
- {
- IServiceCollection services = new ServiceCollection();
- services.AddSingleton(new Logger());
- services.AddMediatR(typeof(Ping), typeof(Ping));
- _provider = services.BuildServiceProvider();
- }
+ IServiceCollection services = new ServiceCollection();
+ services.AddSingleton(new Logger());
+ services.AddMediatR(typeof(Ping), typeof(Ping));
+ _provider = services.BuildServiceProvider();
+ }
- [Fact]
- public void ShouldResolveNotificationHandlersOnlyOnce()
- {
- _provider.GetServices>().Count().ShouldBe(3);
- }
+ [Fact]
+ public void ShouldResolveNotificationHandlersOnlyOnce()
+ {
+ _provider.GetServices>().Count().ShouldBe(3);
}
}
\ No newline at end of file
diff --git a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/Handlers.cs b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/Handlers.cs
index 45f7dcb..4e24184 100644
--- a/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/Handlers.cs
+++ b/test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/Handlers.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests
{
@@ -8,8 +9,8 @@ namespace MediatR.Extensions.Microsoft.DependencyInjection.Tests
public class Ping : IRequest
{
- public string Message { get; set; }
- public Action ThrowAction { get; set; }
+ public string? Message { get; init; }
+ public Action? ThrowAction { get; init; }
}
public class DerivedPing : Ping
@@ -18,22 +19,22 @@ public class DerivedPing : Ping
public class Pong
{
- public string Message { get; set; }
+ public string? Message { get; init; }
}
public class Zing : IRequest
{
- public string Message { get; set; }
+ public string? Message { get; init; }
}
public class Zong
{
- public string Message { get; set; }
+ public string? Message { get; init; }
}
public class Ding : IRequest
{
- public string Message { get; set; }
+ public string? Message { get; init; }
}
public class Pinged : INotification
@@ -43,6 +44,11 @@ public class Pinged : INotification
class InternalPing : IRequest { }
+ public class StreamPing : IStreamRequest
+ {
+ public string? Message { get; init; }
+ }
+
public class GenericHandler : INotificationHandler
{
public Task Handle(INotification notification, CancellationToken cancellationToken)
@@ -125,6 +131,22 @@ public Task Handle(Zing message, CancellationToken cancellationToken)
}
}
+ public class PingStreamHandler : IStreamRequestHandler
+ {
+ private readonly Logger _output;
+
+ public PingStreamHandler(Logger output)
+ {
+ _output = output;
+ }
+ public async IAsyncEnumerable Handle(StreamPing request, [EnumeratorCancellation] CancellationToken cancellationToken)
+ {
+ _output.Messages.Add("Handler");
+ yield return await Task.Run(() => new Pong { Message = request.Message + " Pang" }, cancellationToken);
+ }
+ }
+
+
public class DuplicateTest : IRequest { }
public class DuplicateHandler1 : IRequestHandler
{
@@ -149,12 +171,23 @@ class InternalPingHandler : IRequestHandler
class MyCustomMediator : IMediator
{
- public Task