LuckyPennySoftware/MediatR · error · InvalidOperationException
MediatR requires ILoggerFactory to be registered. Call servi
Error message
MediatR requires ILoggerFactory to be registered. Call services.AddLogging() before services.AddMediatR().
What it means
Thrown from the LicenseAccessor factory registered via TryAddSingleton when the service provider cannot resolve ILoggerFactory. MediatR's licensing subsystem (LicenseAccessor) requires a logger factory to operate, so resolving LicenseAccessor fails fast with an actionable message directing the user to call AddLogging before AddMediatR.
Source
Thrown at src/MediatR/Registration/ServiceRegistrar.cs:477
}
catch (Exception) { /* ignore invalid type constructions */ }
}
}
public static void AddRequiredServices(IServiceCollection services, MediatRServiceConfiguration serviceConfiguration)
{
// Use TryAdd, so any existing ServiceFactory/IMediator registration doesn't get overridden
services.TryAdd(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));
services.TryAdd(new ServiceDescriptor(typeof(ISender), sp => sp.GetRequiredService<IMediator>(), serviceConfiguration.Lifetime));
services.TryAdd(new ServiceDescriptor(typeof(IPublisher), sp => sp.GetRequiredService<IMediator>(), serviceConfiguration.Lifetime));
MediatRServiceCollectionExtensions.LicenseChecked = false;
services.TryAddSingleton(serviceConfiguration);
services.TryAddSingleton<LicenseAccessor>(static sp =>
{
var loggerFactory = sp.GetService<ILoggerFactory>()
?? throw new InvalidOperationException(
"MediatR requires ILoggerFactory to be registered. " +
"Call services.AddLogging() before services.AddMediatR().");
var config = sp.GetService<MediatRServiceConfiguration>();
return config != null
? new LicenseAccessor(config, loggerFactory)
: new LicenseAccessor(loggerFactory);
});
services.TryAddSingleton<LicenseValidator>(static sp =>
{
var loggerFactory = sp.GetService<ILoggerFactory>()
?? throw new InvalidOperationException(
"MediatR requires ILoggerFactory to be registered. " +
"Call services.AddLogging() before services.AddMediatR().");
return new LicenseValidator(loggerFactory);
});
var notificationPublisherServiceDescriptor = serviceConfiguration.NotificationPublisherType != null
? new ServiceDescriptor(typeof(INotificationPublisher), serviceConfiguration.NotificationPublisherType, serviceConfiguration.Lifetime)View on GitHub (pinned to 916ef1b3d6)
Solutions
- Call services.AddLogging() before services.AddMediatR(...) in startup configuration.
- In ASP.NET Core / generic host projects, AddLogging is usually included by host defaults; if removed, add it back.
- For test harnesses, register a Noop logger: services.AddLogging(b => b.SetMinimumLevel(LogLevel.None)); or use the NullLoggerFactory.
Example fix
// before var services = new ServiceCollection(); services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<MyHandler>()); // after var services = new ServiceCollection(); services.AddLogging(); services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<MyHandler>());
Defensive patterns
Strategy: validation
Validate before calling
// Ensure logging is present before AddMediatR
if (!services.Any(s => s.ServiceType == typeof(ILoggerFactory)))
services.AddLogging();
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<MyHandler>()); Type guard
static bool HasLogging(IServiceCollection s) =>
s.Any(d => d.ServiceType == typeof(ILoggerFactory)); Try / catch
try { var mediator = provider.GetRequiredService<IMediator>(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("ILoggerFactory"))
{
logger.LogError(ex, "Add AddLogging() before AddMediatR()");
throw;
} Prevention
- Always call AddLogging() before AddMediatR() in startup.
- Add a startup check asserting ILoggerFactory is registered.
When it happens
Trigger: Calling services.AddMediatR(...) on a ServiceCollection that has not had AddLogging() called, then resolving IMediator (which transitively resolves LicenseAccessor). The exception surfaces at first resolution, not at AddMediatR time.
Common situations: Minimal/console hosts that skip AddLogging; unit tests with a bare ServiceCollection; library-hosting scenarios where logging was assumed present; ordering mistake placing AddMediatR before AddLogging in some configurations.
Related errors
- {openBehaviorType.Name} must implement {typeof(IStreamPipeli
- {implementationType.Name} must implement {typeof(IRequestPre
- {openBehaviorType.Name} must implement {typeof(IRequestPrePr
- {implementationType.Name} must implement {typeof(IRequestPos
- {openBehaviorType.Name} must implement {typeof(IRequestPostP
AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13).
Data as JSON: /api/errors/9cc565c75c461ba8.
Report an issue: GitHub.