Skip to content

Commit f7a1421

Browse files
Fix transient test failures
1 parent ffe5f4b commit f7a1421

4 files changed

Lines changed: 31 additions & 46 deletions

File tree

Questy/Mediator.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public Task Publish(object notification, CancellationToken cancellationToken = d
154154
{
155155
null => throw new ArgumentNullException(nameof(notification)),
156156
INotification instance => PublishNotification(instance, cancellationToken),
157-
_ => throw new ArgumentException($"{nameof(notification)} does not implement ${nameof(INotification)}")
157+
_ => throw new ArgumentException($"'{notification.GetType().Name}' does not implement '{nameof(INotification)}'")
158158
};
159159

160160
/// <summary>
@@ -202,9 +202,7 @@ public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamRequest<TRespo
202202
return (StreamRequestHandlerBase)wrapper;
203203
});
204204

205-
IAsyncEnumerable<TResponse> items = streamHandler.Handle(request, serviceProvider, cancellationToken);
206-
207-
return items;
205+
return streamHandler.Handle(request, serviceProvider, cancellationToken);
208206
}
209207

210208
/// <summary>

Questy/MicrosoftExtensionsDI/ServiceCollectionExtensions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ public static IServiceCollection AddMediator(this IServiceCollection services,
4545
throw new ArgumentException("No assemblies found to scan. Supply at least one assembly to scan for handlers.");
4646
}
4747

48-
ServiceRegistrar.SetGenericRequestHandlerRegistrationLimitations(configuration);
49-
5048
ServiceRegistrar.AddMediatorClassesWithTimeout(services, configuration);
5149

5250
ServiceRegistrar.AddRequiredServices(services, configuration);

Questy/Registration/ServiceRegistrar.cs

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,6 @@ namespace Questy.Registration;
1111
/// </summary>
1212
public static class ServiceRegistrar
1313
{
14-
private static int MaxGenericTypeParameters;
15-
private static int MaxTypesClosing;
16-
private static int MaxGenericTypeRegistrations;
17-
private static int RegistrationTimeout;
18-
19-
/// <summary>
20-
/// Sets the limitations for generic request handler registrations.
21-
/// </summary>
22-
/// <param name="configuration"></param>
23-
public static void SetGenericRequestHandlerRegistrationLimitations(MediatorServiceConfiguration configuration)
24-
{
25-
MaxGenericTypeParameters = configuration.MaxGenericTypeParameters;
26-
MaxTypesClosing = configuration.MaxTypesClosing;
27-
MaxGenericTypeRegistrations = configuration.MaxGenericTypeRegistrations;
28-
RegistrationTimeout = configuration.RegistrationTimeout;
29-
}
30-
3114
/// <summary>
3215
/// Registers the necessary services for Questy, including request handlers, notification handlers,
3316
/// behaviors, and other related services.
@@ -37,16 +20,14 @@ public static void SetGenericRequestHandlerRegistrationLimitations(MediatorServi
3720
/// <exception cref="TimeoutException"></exception>
3821
public static void AddMediatorClassesWithTimeout(IServiceCollection services, MediatorServiceConfiguration configuration)
3922
{
40-
using (CancellationTokenSource cts = new(RegistrationTimeout))
23+
using CancellationTokenSource cts = new(configuration.RegistrationTimeout);
24+
try
4125
{
42-
try
43-
{
44-
AddMediatorClasses(services, configuration, cts.Token);
45-
}
46-
catch (OperationCanceledException)
47-
{
48-
throw new TimeoutException("The generic handler registration process timed out.");
49-
}
26+
AddMediatorClasses(services, configuration, cts.Token);
27+
}
28+
catch (OperationCanceledException)
29+
{
30+
throw new TimeoutException("The generic handler registration process timed out.");
5031
}
5132
}
5233

@@ -181,7 +162,7 @@ private static void ConnectImplementationsToTypesClosing(Type openRequestInterfa
181162
foreach (Type @interface in genericInterfaces)
182163
{
183164
List<Type> exactMatches = genericConcretions.Where(x => x.CanBeCastTo(@interface)).ToList();
184-
AddAllConcretionsThatClose(@interface, exactMatches, services, assembliesToScan, cancellationToken);
165+
AddAllConcretionsThatClose(@interface, exactMatches, services, assembliesToScan, configuration, cancellationToken);
185166
}
186167
}
187168

@@ -240,9 +221,9 @@ private static (Type Service, Type Implementation) GetConcreteRegistrationTypes(
240221
return (serviceType, openRequestHandlerImplementation.MakeGenericType(closingTypes));
241222
}
242223

243-
private static List<Type>? GetConcreteRequestTypes(Type openRequestHandlerInterface, Type openRequestHandlerImplementation, IEnumerable<Assembly> assembliesToScan, CancellationToken cancellationToken)
224+
private static List<Type>? GetConcreteRequestTypes(Type openRequestHandlerInterface, Type openRequestHandlerImplementation, IEnumerable<Assembly> assembliesToScan, MediatorServiceConfiguration configuration, CancellationToken cancellationToken)
244225
{
245-
//request generic type constraints
226+
//request generic type constraints
246227
List<Type[]> constraintsForEachParameter = openRequestHandlerImplementation
247228
.GetGenericArguments()
248229
.Select(x => x.GetGenericParameterConstraints())
@@ -261,7 +242,7 @@ private static (Type Service, Type Implementation) GetConcreteRegistrationTypes(
261242

262243
Type requestGenericTypeDefinition = requestType.GetGenericTypeDefinition();
263244

264-
List<List<Type>> combinations = GenerateCombinations(requestType, typesThatCanCloseForEachParameter, 0, cancellationToken);
245+
List<List<Type>> combinations = GenerateCombinations(requestType, typesThatCanCloseForEachParameter, configuration.MaxGenericTypeParameters, configuration.MaxTypesClosing, configuration.MaxGenericTypeRegistrations, 0, cancellationToken);
265246

266247
return combinations.Select(types => requestGenericTypeDefinition.MakeGenericType(types.ToArray())).ToList();
267248
}
@@ -276,26 +257,29 @@ private static (Type Service, Type Implementation) GetConcreteRegistrationTypes(
276257
/// <returns></returns>
277258
/// <exception cref="ArgumentException"></exception>
278259
public static List<List<Type>> GenerateCombinations(Type requestType, List<List<Type>> lists, int depth = 0, CancellationToken cancellationToken = default)
260+
=> GenerateCombinations(requestType, lists, 0, 0, 0, depth, cancellationToken);
261+
262+
private static List<List<Type>> GenerateCombinations(Type requestType, List<List<Type>> lists, int maxGenericTypeParameters, int maxTypesClosing, int maxGenericTypeRegistrations, int depth, CancellationToken cancellationToken)
279263
{
280264
if (depth == 0)
281265
{
282266
// Initial checks
283-
if (MaxGenericTypeParameters > 0 && lists.Count > MaxGenericTypeParameters)
284-
throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. The number of generic type parameters exceeds the maximum allowed ({MaxGenericTypeParameters}).");
267+
if (maxGenericTypeParameters > 0 && lists.Count > maxGenericTypeParameters)
268+
throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. The number of generic type parameters exceeds the maximum allowed ({maxGenericTypeParameters}).");
285269

286270
foreach (List<Type> list in lists)
287271
{
288-
if (MaxTypesClosing > 0 && list.Count > MaxTypesClosing)
289-
throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. One of the generic type parameter's count of types that can close exceeds the maximum length allowed ({MaxTypesClosing}).");
272+
if (maxTypesClosing > 0 && list.Count > maxTypesClosing)
273+
throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. One of the generic type parameter's count of types that can close exceeds the maximum length allowed ({maxTypesClosing}).");
290274
}
291275

292276
// Calculate the total number of combinations
293277
long totalCombinations = 1;
294278
foreach (List<Type> list in lists)
295279
{
296280
totalCombinations *= list.Count;
297-
if (MaxGenericTypeParameters > 0 && totalCombinations > MaxGenericTypeRegistrations)
298-
throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. The total number of generic type registrations exceeds the maximum allowed ({MaxGenericTypeRegistrations}).");
281+
if (maxGenericTypeParameters > 0 && totalCombinations > maxGenericTypeRegistrations)
282+
throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. The total number of generic type registrations exceeds the maximum allowed ({maxGenericTypeRegistrations}).");
299283
}
300284
}
301285

@@ -305,7 +289,7 @@ public static List<List<Type>> GenerateCombinations(Type requestType, List<List<
305289
cancellationToken.ThrowIfCancellationRequested();
306290

307291
List<Type> currentList = lists[depth];
308-
List<List<Type>> childCombinations = GenerateCombinations(requestType, lists, depth + 1, cancellationToken);
292+
List<List<Type>> childCombinations = GenerateCombinations(requestType, lists, maxGenericTypeParameters, maxTypesClosing, maxGenericTypeRegistrations, depth + 1, cancellationToken);
309293
List<List<Type>> combinations = new();
310294

311295
foreach (Type item in currentList)
@@ -321,11 +305,11 @@ public static List<List<Type>> GenerateCombinations(Type requestType, List<List<
321305
return combinations;
322306
}
323307

324-
private static void AddAllConcretionsThatClose(Type openRequestInterface, List<Type> concretions, IServiceCollection services, IEnumerable<Assembly> assembliesToScan, CancellationToken cancellationToken)
308+
private static void AddAllConcretionsThatClose(Type openRequestInterface, List<Type> concretions, IServiceCollection services, IEnumerable<Assembly> assembliesToScan, MediatorServiceConfiguration configuration, CancellationToken cancellationToken)
325309
{
326310
foreach (Type concretion in concretions)
327311
{
328-
List<Type>? concreteRequests = GetConcreteRequestTypes(openRequestInterface, concretion, assembliesToScan, cancellationToken);
312+
List<Type>? concreteRequests = GetConcreteRequestTypes(openRequestInterface, concretion, assembliesToScan, configuration, cancellationToken);
329313

330314
if (concreteRequests is null)
331315
continue;

Tests/Questy.Tests/NotificationPublisherTests.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ public async Task Handle(Notification notification, CancellationToken cancellati
2626
}
2727
public class SecondHandler : INotificationHandler<Notification>
2828
{
29-
public async Task Handle(Notification notification, CancellationToken cancellationToken)
29+
public async Task Handle(Notification notification, CancellationToken cancellationToken)
30+
=> await Task.Delay(250, cancellationToken);
31+
}
32+
public class ThirdHandler : INotificationHandler<Notification>
33+
{
34+
public async Task Handle(Notification notification, CancellationToken cancellationToken)
3035
=> await Task.Delay(250, cancellationToken);
3136
}
3237

0 commit comments

Comments
 (0)