Unable to resolve ILogger from Microsoft.Extensions.Logging
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The “unable to resolve ILogger” error in .NET usually means the dependency injection container was asked for the wrong logging type. In the built-in logging system, the normal constructor dependency is ILogger<TCategoryName>, not the non-generic ILogger interface by itself.
Why Plain ILogger Often Fails
The logging system is category-based. When you request ILogger<Worker>, the container knows the category should be the fully qualified name of Worker.
If you request plain ILogger, the container has no category type to infer automatically. That is why resolution often fails even though logging is otherwise configured correctly.
Prefer ILogger<T> in Application Services
If a service currently looks like this:
Change it to this:
That is the standard pattern in ASP.NET Core, worker services, and console apps that use the default host and container.
Make Sure Logging Is Registered
Using the right constructor type is only part of the fix. Logging services must also be registered in the container.
When you use the generic host, this is usually done for you:
If you build a ServiceCollection manually, you need to add logging yourself:
Without AddLogging, even ILogger<Worker> will not be available.
Use ILoggerFactory for Dynamic Categories
Sometimes you really do need a non-generic logger. In that case, inject ILoggerFactory and create the logger explicitly:
This is appropriate when the category is not naturally tied to a single class type. The important point is that you still let the framework create the logger, rather than asking DI to infer a category from plain ILogger.
Watch How the Object Is Created
Another common source of confusion is bypassing the container:
If the service is created manually with new, dependency injection does not participate. That means no logger gets supplied, regardless of how correctly the container was configured elsewhere.
When constructor injection is part of the design, the service should be resolved from DI:
This sounds obvious, but it shows up often in test code, quick console prototypes, and old codebases gradually moving toward DI.
Provider Configuration Is Separate
Providers such as Console logging, Serilog, or Application Insights affect where logs go. They do not change the core DI rule about ILogger<T>.
In other words, the following are separate concerns:
- can the container resolve a logger dependency
- which provider writes the resulting log entries
Mixing those up leads people to blame the provider package when the actual issue is constructor type or missing AddLogging.
Common Pitfalls
- Injecting plain
ILoggerinstead ofILogger<T>. - Forgetting to call
AddLoggingwhen building a rawServiceCollection. - Creating services manually with
newand expecting dependency injection to fill constructor arguments. - Blaming the logging provider when the actual issue is DI registration or type choice.
- Mixing multiple startup paths and only configuring logging in one of them.
Summary
- In most .NET services, inject
ILogger<T>rather than plainILogger. - Ensure logging services are registered, especially in manually built containers.
- Use
ILoggerFactorywhen you need a non-generic logger with a dynamic category. - Resolve services from the DI container instead of constructing them manually.
- Separate logger resolution issues from provider configuration issues when troubleshooting.

