{"record":{"id":"9cc565c75c461ba8","repo":"LuckyPennySoftware/MediatR","slug":"mediatr-requires-iloggerfactory-to-be-registered","errorCode":null,"errorMessage":"MediatR requires ILoggerFactory to be registered. Call services.AddLogging() before services.AddMediatR().","messagePattern":"MediatR requires ILoggerFactory to be registered\\. Call services\\.AddLogging\\(\\) before services\\.AddMediatR\\(\\)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MediatR/Registration/ServiceRegistrar.cs","lineNumber":477,"sourceCode":"            }\n            catch (Exception) { /* ignore invalid type constructions */ }\n        }\n    }\n\n    public static void AddRequiredServices(IServiceCollection services, MediatRServiceConfiguration serviceConfiguration)\n    {\n        // Use TryAdd, so any existing ServiceFactory/IMediator registration doesn't get overridden\n        services.TryAdd(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));\n        services.TryAdd(new ServiceDescriptor(typeof(ISender), sp => sp.GetRequiredService<IMediator>(), serviceConfiguration.Lifetime));\n        services.TryAdd(new ServiceDescriptor(typeof(IPublisher), sp => sp.GetRequiredService<IMediator>(), serviceConfiguration.Lifetime));\n\n        MediatRServiceCollectionExtensions.LicenseChecked = false;\n        \n        services.TryAddSingleton(serviceConfiguration);\n        services.TryAddSingleton<LicenseAccessor>(static sp =>\n        {\n            var loggerFactory = sp.GetService<ILoggerFactory>()\n                ?? throw new InvalidOperationException(\n                    \"MediatR requires ILoggerFactory to be registered. \" +\n                    \"Call services.AddLogging() before services.AddMediatR().\");\n            var config = sp.GetService<MediatRServiceConfiguration>();\n            return config != null\n                ? new LicenseAccessor(config, loggerFactory)\n                : new LicenseAccessor(loggerFactory);\n        });\n        services.TryAddSingleton<LicenseValidator>(static sp =>\n        {\n            var loggerFactory = sp.GetService<ILoggerFactory>()\n                ?? throw new InvalidOperationException(\n                    \"MediatR requires ILoggerFactory to be registered. \" +\n                    \"Call services.AddLogging() before services.AddMediatR().\");\n            return new LicenseValidator(loggerFactory);\n        });\n\n        var notificationPublisherServiceDescriptor = serviceConfiguration.NotificationPublisherType != null\n            ? new ServiceDescriptor(typeof(INotificationPublisher), serviceConfiguration.NotificationPublisherType, serviceConfiguration.Lifetime)","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/LuckyPennySoftware/MediatR/blob/916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5/src/MediatR/Registration/ServiceRegistrar.cs#L459-L495","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar services = new ServiceCollection();\nservices.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<MyHandler>());\n\n// after\nvar services = new ServiceCollection();\nservices.AddLogging();\nservices.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<MyHandler>());","handlingStrategy":"validation","validationCode":"// Ensure logging is present before AddMediatR\nif (!services.Any(s => s.ServiceType == typeof(ILoggerFactory)))\n    services.AddLogging();\nservices.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<MyHandler>());","typeGuard":"static bool HasLogging(IServiceCollection s) =>\n    s.Any(d => d.ServiceType == typeof(ILoggerFactory));","tryCatchPattern":"try { var mediator = provider.GetRequiredService<IMediator>(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"ILoggerFactory\"))\n{\n    logger.LogError(ex, \"Add AddLogging() before AddMediatR()\");\n    throw;\n}","preventionTips":["Always call AddLogging() before AddMediatR() in startup.","Add a startup check asserting ILoggerFactory is registered."],"tags":["di-registration","logging","licensing","configuration","ordering"],"backgroundTag":null,"analyzedSha":"916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5","analyzedAt":"2026-08-13T17:57:04.476Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}