gpt4 book ai didi

c# - 从应用程序代码调用 'BuildServiceProvider' 会导致复制单例警告。我如何避免这种情况?

转载 作者:行者123 更新时间:2023-12-04 04:25:10 24 4
gpt4 key购买 nike

我刚刚从另一个项目的最后粘贴了 4 行,它可以工作,但我收到警告..我显然不太了解 DI ......它想让我改变什么?

  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>();

services.Configure<RAFLogging>(Configuration.GetSection("RAFLogging"));
ServiceProvider serviceProvider = services.BuildServiceProvider(); //WARNING IS HERE
IOptions<RAFLogging> RAFLogger = serviceProvider.GetRequiredService<IOptions<RAFLogging>>();
RegisterSerilogLogger logger = new RegisterSerilogLogger(RAFLogger);
}

最佳答案

如果在 ConfigureServices 中调用 BuildServiceProvider(),则会显示警告“从应用程序代码调用‘BuildServiceProvider’会导致创建单例服务的附加副本”
我解决了这个问题:
创建另一个函数(传递的参数是 IServiceCollection)并进入函数调用 BuildServiceProvider()
enter image description here
例如你的代码应该是:

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;
}
或者使用 IApplicationBuilder 的 ApplicationServices。 ApplicationServices 的类型是 IServiceProvider。
我提到这个解决方案仅适用于 删除警告 .
调用 BuildServiceProvider 会创建第二个容器,该容器可以创建撕裂的单例并导致对跨多个容器的对象图的引用。

2021 年 1 月 24 日更新
我读了亚当·弗里曼的 Pro ASP.NET Core 3 8th书。亚当·弗里曼使用过 app.ApplicationServices而不是 services.BuildServiceProvider()为此,在第 157 页中,该应用程序是此方法位于 Startup.cs 中的配置方法的参数
我想 正确的版本是使用应用程序的 ApplicationServices 属性,该应用程序是 Configure 方法参数中的 IApplicationBuilder。 ApplicationServices 的类型是 IServiceProvider。
enter image description here
Adam Freeman 的 Pro ASP.NET Core 3 第 8 本书: Pro ASP.NET Core 3
Adam Freeman 的示例项目: SportStore project's Startup.cs , SportStore project's SeedData.cs
微软关于 DI 的建议: Dependency injection in ASP.NET Core
Stackoverflow 中类似问题的回答: https://stackoverflow.com/a/56058498/8810311 , https://stackoverflow.com/a/56278027/8810311

关于c# - 从应用程序代码调用 'BuildServiceProvider' 会导致复制单例警告。我如何避免这种情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58999401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com