Calling 'BuildServiceProvider' From Application Code Results In Copy Of Singleton Warning. How Do I Avoid This?
Answer :
If called BuildServiceProvider() in ConfigureServices, shown warning "Calling 'BuildServiceProvider' from application code results in a additional copy of Singleton services being created"
I solved this issue:
Create another function (which passed argument is IServiceCollection) and into the function call BuildServiceProvider()

For example your code it should be:
public void ConfigureServices(IServiceCollection services) {     if (HostingEnvironment.EnvironmentName == "Local")     {         services.AddHealthChecksUI()         .AddHealthChecks()         .AddCheck<TestWebApiControllerHealthCheck>("HomePageHealthCheck")         .AddCheck<DatabaseHealthCheck>("DatabaseHealthCheck");     }      services.Configure<PwdrsSettings>(Configuration.GetSection("MySettings"));     services.AddDbContext<PwdrsContext>(o => o.UseSqlServer(Configuration.GetConnectionString("PwdrsConnectionRoot")));      services.AddMvc(o =>     {         o.Filters.Add<CustomExceptionFilter>();     });      services.AddCors(options =>     {         options.AddPolicy("CorsPolicy", b => b             .SetIsOriginAllowed((host) => true)             .AllowAnyMethod()             .AllowAnyHeader()             .AllowCredentials());     });      services.AddSwaggerDocument();     services.AddHttpContextAccessor();      services.AddAutoMapper(typeof(ObjectMapperProfile));     services.AddTransient<IEmailSender, EmailSender>();     services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>));     services.AddScoped(typeof(IAsyncRepository<>), typeof(Repository<>));     services.AddScoped<IRfReportTypeRepository, RfReportTypeRepository>();     services.AddScoped<IRfReportRepository, RfReportRepository>();     services.AddScoped<IRfReportLookupsService, RfReportLookupsService>();     services.AddScoped<IRfReportService, RfReportService>();      RegisterSerilogLogger logger = CreateRegisterSerilogLogger(services); }  private RegisterSerilogLogger CreateRegisterSerilogLogger(IServiceCollection services){         services.Configure<RAFLogging>(Configuration.GetSection("RAFLogging"));         ServiceProvider serviceProvider = services.BuildServiceProvider(); //No warning here ))         IOptions<RAFLogging> RAFLogger = serviceProvider.GetRequiredService<IOptions<RAFLogging>>();         RegisterSerilogLogger logger = new RegisterSerilogLogger(RAFLogger);     return logger; } Or use ApplicationServices of IApplicationBuilder. ApplicationSerivces's type is IServiceProvider.
I mention this solution is only for remove warning.
Calling BuildServiceProvider creates a second container, which can create torn singletons and cause references to object graphs across multiple containers.
UPDATED 24.01.2021
I read Adam Freeman's Pro ASP.NET Core 3 8th book. Adam Freeman used app.ApplicationServices instead of services.BuildServiceProvider() in page 157 for this purpose, that app is Configure method's parameter that this method located in Startup.cs
I thinks correct version is to use ApplicationServices property of app, which app is IApplicationBuilder in Configure method's parameter. ApplicationServices's type is IServiceProvider.

Adam Freeman's Pro ASP.NET Core 3 8th book : Pro ASP.NET Core 3
Adam Freeman's example project: SportStore project's Startup.cs, SportStore project's SeedData.cs
Microsoft's recommendations about DI : Dependency injection in ASP.NET Core
Similar questions' answers in Stackoverflow: https://stackoverflow.com/a/56058498/8810311, https://stackoverflow.com/a/56278027/8810311
Comments
Post a Comment