Skip to content

Commit e59123b

Browse files
committed
Always assert no compilation errors or warnings in unit tests
1 parent 6141e39 commit e59123b

12 files changed

+551
-161
lines changed

src/Foundatio.Mediator/EndpointGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ private static string GenerateEndpointCode(List<HandlerInfo> handlers, EndpointD
271271
using Microsoft.AspNetCore.Http;
272272
using Microsoft.AspNetCore.Routing;
273273
using System.Diagnostics.CodeAnalysis;
274+
using System.Linq;
274275
""");
275276

276277
if (hasAnySseEndpoints)

src/Foundatio.Mediator/HandlerGenerator.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,11 @@ private static string BuildExecuteParameters(IndentedStringBuilder source, Equat
482482
}
483483
else
484484
{
485-
// DI parameter
486-
parameterValues.Add($"serviceProvider.GetRequiredService<{param.Type.FullName}>()");
485+
// DI parameter — use GetService for nullable types to avoid notnull constraint violation
486+
if (param.Type.IsNullable)
487+
parameterValues.Add($"serviceProvider.GetService<{param.Type.UnwrappedFullName}>()");
488+
else
489+
parameterValues.Add($"serviceProvider.GetRequiredService<{param.Type.FullName}>()");
487490
}
488491
}
489492

@@ -1170,7 +1173,11 @@ private static string BuildParameters(IndentedStringBuilder source, EquatableArr
11701173
}
11711174
else
11721175
{
1173-
parameterValues.Add($"serviceProvider.GetRequiredService<{param.Type.FullName}>()");
1176+
// DI parameter — use GetService for nullable types to avoid notnull constraint violation
1177+
if (param.Type.IsNullable)
1178+
parameterValues.Add($"serviceProvider.GetService<{param.Type.UnwrappedFullName}>()");
1179+
else
1180+
parameterValues.Add($"serviceProvider.GetRequiredService<{param.Type.FullName}>()");
11741181
}
11751182
}
11761183

src/Foundatio.Mediator/MediatorGenerator.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,22 @@ private static void Execute(
275275
var crossAssemblyCallSites = new List<CallSiteInfo>();
276276
var crossAssemblyHandlerMessageTypes = new HashSet<string>(crossAssemblyHandlerList.Select(h => h.MessageType.FullName));
277277

278+
// Find message types with multiple local handlers — these are ambiguous and
279+
// must NOT have interceptors generated (would cause CS9153: intercepted multiple times).
280+
var ambiguousMessageTypes = new HashSet<string>(filteredHandlers
281+
.GroupBy(h => h.MessageType.FullName)
282+
.Where(g => g.Count() > 1)
283+
.Select(g => g.Key));
284+
278285
var handlersWithInfo = new List<HandlerInfo>();
279286
foreach (var handler in filteredHandlers)
280287
{
281-
callSitesByMessage.TryGetValue(handler.MessageType, out var handlerCallSites);
288+
// Don't assign call sites when multiple handlers exist for the same message type,
289+
// since each would generate an interceptor for the same call site.
290+
CallSiteInfo[]? handlerCallSites = null;
291+
if (!ambiguousMessageTypes.Contains(handler.MessageType.FullName))
292+
callSitesByMessage.TryGetValue(handler.MessageType, out handlerCallSites);
293+
282294
var applicableMiddleware = GetApplicableMiddlewares(allMiddleware.ToImmutableArray(), handler, configuration, out var orderingDiagnostics);
283295

284296
// Resolve effective handler lifetime: use explicit lifetime if set, otherwise use project default
@@ -287,7 +299,7 @@ private static void Execute(
287299
// Merge assembly-level authorization defaults into handler authorization info
288300
var mergedAuth = MergeAuthorizationDefaults(handler.Authorization, endpointDefaults);
289301

290-
handlersWithInfo.Add(handler with { CallSites = new(handlerCallSites), Middleware = applicableMiddleware, Lifetime = resolvedHandlerLifetime, OrderingDiagnostics = new(orderingDiagnostics.ToArray()), Authorization = mergedAuth });
302+
handlersWithInfo.Add(handler with { CallSites = new(handlerCallSites ?? []), Middleware = applicableMiddleware, Lifetime = resolvedHandlerLifetime, OrderingDiagnostics = new(orderingDiagnostics.ToArray()), Authorization = mergedAuth });
291303
}
292304

293305
// Collect call sites that need cross-assembly interceptors

tests/Foundatio.Mediator.Tests/BasicHandlerGenerationTests.EndpointGeneration.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ using Microsoft.AspNetCore.Builder;
148148
using Microsoft.AspNetCore.Http;
149149
using Microsoft.AspNetCore.Routing;
150150
using System.Diagnostics.CodeAnalysis;
151+
using System.Linq;
151152

152153
namespace Foundatio.Mediator;
153154

0 commit comments

Comments
 (0)