Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger`1[WebApplication1.Startup]'
Solution 1
Unfortunately, it's not possible to inject ILogger
into Startup.cs in ASP.NET Core 3.0 anymore.
Note
In ASP.NET Core 3.0 and later, it is no longer possible to inject ILogger in Startup.cs and Program.cs. See https://github.com/aspnet/Announcements/issues/353 for more details.
EDIT: A possible way of doing logging inside the Configure method in Startup.cs would be:
using (var logScope = app.ApplicationServices.CreateScope())
{
var logger = logScope.ServiceProvider.GetService<ILogger<Startup>>();
logger.LogInformation("Some information");
}
Solution 2
This can be solved by registering the ILogger
manually to use the Startup class as type.
Example:
public void ConfigureServices(IServiceCollection services)
{
// Normal AddLogging
services.AddLogging();
// Additional code to register the ILogger as a ILogger<T> where T is the Startup class
services.AddSingleton(typeof(ILogger), typeof(Logger<Startup>));
// ...
}
Solution 3
If you want to log things after the Configure() has been called, you can still inject the ILogger via method injection (as opposed to the preferred constructor injection:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<TStartup> logger)
{
_logger = logger;
...
}
Solution 4
This issue is related with IHostBuilder
.
For a temp workaround, I suggest you try IWebHost
to replace IHostBuilder
.
Change your Program.cs like
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
})
.Build();
}
Solution 5
Since dotnet 3.0, web applications use IHostBuilder instead of IWebHostBuilder. So it is no longer possible to directly inject an ILogger in the Startup class.
https://github.com/dotnet/docs/issues/14900
You can get around this by directly creating your logger for the Startup class in your builder.
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args)
.Build()
.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureLogging(AppLoggingConfiguration)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
.UseWindowsService();
}
public static void AppLoggingConfiguration(ILoggingBuilder loggingBuilder)
{
loggingBuilder.ClearProviders();
loggingBuilder.AddDebug();
loggingBuilder.AddConsole();
loggingBuilder.AddEventLog(new EventLogSettings
{
SourceName = "MySourceName",
LogName = "Application",
});
}
}
Startup.cs
public class Startup
{
private readonly ILogger<Startup> _logger;
public Startup(IConfiguration configuration)
{
this.Configuration = configuration;
var lf = LoggerFactory.Create(Program.AppLoggingConfiguration);
_logger = lf.CreateLogger<Startup>();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
/// ...
_logger.LogInformation("Hello startup");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
/// ...
}
}
Chris
Updated on July 09, 2022Comments
-
Chris almost 2 years
I created an ASP.NET Core 3.0 Web Application with the default template in Visual Studio 2019 Preview 2.2 and tried to inject an ILogger in Startup:
namespace WebApplication1 { public class Startup { private readonly ILogger _logger; public Startup(IConfiguration configuration, ILogger<Startup> logger) { Configuration = configuration; _logger = logger; } // ... } }
In Program.cs I also call the ConfigureLogging() method:
namespace WebApplication1 { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.ClearProviders(); logging.AddConsole(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } }
It works in ASP.NET Core 2.x but in ASP.NET Core 3 it fails with the following error:
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger`1[WebApplication1.Startup]' while attempting to activate 'WebApplication1.Startup'. at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) at Microsoft.AspNetCore.Hosting.Internal.GenericWebHostBuilder.UseStartup(Type startupType, HostBuilderContext context, IServiceCollection services) --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.Internal.GenericWebHostBuilder.<>c__DisplayClass13_0.<UseStartup>b__2(IApplicationBuilder app) at Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter.<>c__DisplayClass2_0.<Configure>b__0(IApplicationBuilder app) at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app) at Microsoft.AspNetCore.Hosting.Internal.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
Any idea on what is causing this behavior?
Below the full Program.cs and Startup.cs files from the default "Web Application" template, only logging was added.
Program.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace WebApplication1 { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.ClearProviders(); logging.AddConsole(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } }
Startup.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace WebApplication1 { public class Startup { private readonly ILogger _logger; public Startup(IConfiguration configuration, ILogger<Startup> logger) { Configuration = configuration; _logger = logger; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); //services.AddTransient(typeof(ILogger<>), (typeof(Logger<>))); services.AddMvc() .AddNewtonsoftJson(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(routes => { routes.MapApplication(); }); app.UseCookiePolicy(); app.UseAuthorization(); } } }