diff --git a/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs b/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs index 5dae21d0..bc785f91 100644 --- a/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs +++ b/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs @@ -92,7 +92,7 @@ public class MediatRServiceConfiguration /// /// Flag that controlls whether MediatR will attempt to register handlers that containg generic type parameters. /// - public bool RegisterGenericHandlers { get; set; } = true; + public bool RegisterGenericHandlers { get; set; } = false; /// /// Register various handlers from assembly containing given type diff --git a/src/MediatR/Registration/ServiceRegistrar.cs b/src/MediatR/Registration/ServiceRegistrar.cs index c4cdd008..5d22cc8f 100644 --- a/src/MediatR/Registration/ServiceRegistrar.cs +++ b/src/MediatR/Registration/ServiceRegistrar.cs @@ -228,10 +228,7 @@ private static (Type Service, Type Implementation) GetConcreteRegistrationTypes( var constraintsForEachParameter = openRequestHandlerImplementation .GetGenericArguments() .Select(x => x.GetGenericParameterConstraints()) - .ToList(); - - if (constraintsForEachParameter.Count > 2 && constraintsForEachParameter.Any(constraints => !constraints.Where(x => x.IsInterface || x.IsClass).Any())) - throw new ArgumentException($"Error registering the generic handler type: {openRequestHandlerImplementation.FullName}. When registering generic requests with more than two type parameters, each type parameter must have at least one constraint of type interface or class."); + .ToList(); var typesThatCanCloseForEachParameter = constraintsForEachParameter .Select(constraints => assembliesToScan diff --git a/test/MediatR.Tests/GenericRequestHandlerTests.cs b/test/MediatR.Tests/GenericRequestHandlerTests.cs index 3daa17e6..e6944e3e 100644 --- a/test/MediatR.Tests/GenericRequestHandlerTests.cs +++ b/test/MediatR.Tests/GenericRequestHandlerTests.cs @@ -32,6 +32,7 @@ public void ShouldResolveAllCombinationsOfGenericHandler(int numberOfClasses, in services.AddMediatR(cfg => { cfg.RegisterServicesFromAssemblies(dynamicAssembly); + cfg.RegisterGenericHandlers = true; }); var provider = services.BuildServiceProvider(); @@ -93,24 +94,6 @@ public void ShouldNotRegisterDuplicateHandlers(int numberOfClasses, int numberOf hasDuplicates.ShouldBeFalse(); } - [Fact] - public void ShouldThrowExceptionWhenRegisterningHandlersWithNoConstraints() - { - IServiceCollection services = new ServiceCollection(); - services.AddSingleton(new Logger()); - - var assembly = GenerateMissingConstraintsAssembly(); - - Should.Throw(() => - { - services.AddMediatR(cfg => - { - cfg.RegisterServicesFromAssembly(assembly); - }); - }) - .Message.ShouldContain("When registering generic requests with more than two type parameters, each type parameter must have at least one constraint of type interface or class."); - } - [Fact] public void ShouldThrowExceptionWhenTypesClosingExceedsMaximum() { @@ -124,6 +107,7 @@ public void ShouldThrowExceptionWhenTypesClosingExceedsMaximum() services.AddMediatR(cfg => { cfg.RegisterServicesFromAssembly(assembly); + cfg.RegisterGenericHandlers = true; }); }) .Message.ShouldContain("One of the generic type parameter's count of types that can close exceeds the maximum length allowed"); @@ -142,6 +126,7 @@ public void ShouldThrowExceptionWhenGenericHandlerRegistrationsExceedsMaximum() services.AddMediatR(cfg => { cfg.RegisterServicesFromAssembly(assembly); + cfg.RegisterGenericHandlers = true; }); }) .Message.ShouldContain("The total number of generic type registrations exceeds the maximum allowed"); @@ -160,6 +145,7 @@ public void ShouldThrowExceptionWhenGenericTypeParametersExceedsMaximum() services.AddMediatR(cfg => { cfg.RegisterServicesFromAssembly(assembly); + cfg.RegisterGenericHandlers = true; }); }) .Message.ShouldContain("The number of generic type parameters exceeds the maximum allowed"); @@ -181,6 +167,7 @@ public void ShouldThrowExceptionWhenTimeoutOccurs() cfg.MaxGenericTypeRegistrations = 0; cfg.MaxTypesClosing = 0; cfg.RegistrationTimeout = 1000; + cfg.RegisterGenericHandlers = true; cfg.RegisterServicesFromAssembly(assembly); }); }) diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs index 60575620..6e27757e 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/AssemblyResolutionTests.cs @@ -15,7 +15,11 @@ public AssemblyResolutionTests() { IServiceCollection services = new ServiceCollection(); services.AddSingleton(new Logger()); - services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Ping).Assembly)); + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssembly(typeof(Ping).Assembly); + cfg.RegisterGenericHandlers = true; + }); _provider = services.BuildServiceProvider(); } diff --git a/test/MediatR.Tests/MicrosoftExtensionsDI/BaseGenericRequestHandlerTests.cs b/test/MediatR.Tests/MicrosoftExtensionsDI/BaseGenericRequestHandlerTests.cs index b87fc02b..72853099 100644 --- a/test/MediatR.Tests/MicrosoftExtensionsDI/BaseGenericRequestHandlerTests.cs +++ b/test/MediatR.Tests/MicrosoftExtensionsDI/BaseGenericRequestHandlerTests.cs @@ -9,11 +9,7 @@ namespace MediatR.Tests.MicrosoftExtensionsDI { public abstract class BaseGenericRequestHandlerTests - { - - protected static Assembly GenerateMissingConstraintsAssembly() => - CreateAssemblyModuleBuilder("MissingConstraintsAssembly", 3, 3, CreateHandlerForMissingConstraintsTest); - + { protected static Assembly GenerateTypesClosingExceedsMaximumAssembly() => CreateAssemblyModuleBuilder("ExceedsMaximumTypesClosingAssembly", 201, 1, CreateHandlerForExceedsMaximumClassesTest); diff --git a/test/MediatR.Tests/SendTests.cs b/test/MediatR.Tests/SendTests.cs index 553c689c..abbf7717 100644 --- a/test/MediatR.Tests/SendTests.cs +++ b/test/MediatR.Tests/SendTests.cs @@ -18,7 +18,11 @@ public SendTests() { _dependency = new Dependency(); var services = new ServiceCollection(); - services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(typeof(Ping).Assembly)); + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssemblies(typeof(Ping).Assembly); + cfg.RegisterGenericHandlers = true; + }); services.AddSingleton(_dependency); _serviceProvider = services.BuildServiceProvider(); _mediator = _serviceProvider.GetService()!; @@ -248,8 +252,13 @@ public async Task Should_resolve_closed_handler_if_defined() { var dependency = new Dependency(); var services = new ServiceCollection(); - services.AddSingleton(dependency); - services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly())); + services.AddSingleton(dependency); + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly()); + cfg.RegisterGenericHandlers = true; + }); + services.AddTransient>,TestClass1PingRequestHandler>(); var serviceProvider = services.BuildServiceProvider(); var mediator = serviceProvider.GetService()!; @@ -267,7 +276,11 @@ public async Task Should_resolve_open_handler_if_not_defined() var dependency = new Dependency(); var services = new ServiceCollection(); services.AddSingleton(dependency); - services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly())); + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly()); + cfg.RegisterGenericHandlers = true; + }); services.AddTransient>, TestClass1PingRequestHandler>(); var serviceProvider = services.BuildServiceProvider(); var mediator = serviceProvider.GetService()!;