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

  1. Call services.AddLogging() before services.AddMediatR(...) in startup configuration.
  2. In ASP.NET Core / generic host projects, AddLogging is usually included by host defaults; if removed, add it back.
  3. 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

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


AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13). Data as JSON: /api/errors/9cc565c75c461ba8. Report an issue: GitHub.