asp.net-core - 如何有条件地禁用 ASP.NET Core 中的 Application Insights?
问题描述
当有条件地在我的 ASP.NET Core 应用程序中包含 Application Insights 时,我试图避免 ASP.NET Core 中的服务定位器模式,原因是我想在开发过程中完全禁用 Applications Insights。
服务定位器模式(不推荐)
执行此操作的最基本方法是在使用IServiceCollection 上的方法构建服务提供者之后服务定位IOptions
设置ConfigureServices()
BuildServiceProvider()
(不推荐!)服务定位器模式示例:
public void ConfigureService(IServiceCollection services)
{
// Configure the services
services.Configure<AppSettings>(configuration.GetSection(nameof(AppSettings)));
// Build an intermediate service provider
var sp = services.BuildServiceProvider();
// Resolve the settings from the service provider;
var appSettings = sp.GetRequiredService<AppSettings>();
// Conditionally include the service using the settings
if (appSettings.EnableApplicationInsights) {
services.AddApplicationInsightsTelemetry();
}
}
这不是推荐的模式,因为它会导致创建单例服务的额外副本。但我们可以确定 Application Insights 在应用程序中完全禁用,实际上它甚至不包含在 DI 容器中。
更好的模式#1
解决依赖于其他服务的类的更好方法是使用为您提供 IServiceProvider 的 AddXXX 重载。这样您就不需要实例化中间服务提供者。
以下示例展示了如何在 AddSingleton/AddTransient 方法中使用此重载。
services.AddSingleton(serviceProvider =>
{
var settings = serviceProvider.GetRequiredService<AppSettings>();
var fooService = new FooService();
fooService.Enable = settings.EnableFooService
return fooService;
});
services.AddTransient(serviceProvider =>
{
var settings = serviceProvider.GetRequiredService<AppSettings>();
var barService = new BarService();
barService.Enable = settings.EnableBarService
return barService;
});
IServiceProvider 的重载可用于即 AddSingleton、AddScoped、AddTransient。这种模式效果很好并且易于实现,但服务通常具有AddFoo()
不提供这种重载的方法,即 AddApplicationInsightsTelemetry、AddCors、AddAuthentication、AddAuthorization...
我从 Ehsan Mirsaeedi 的回答中得到灵感: https ://stackoverflow.com/a/56278027/294242
更好的模式#2
我们可以实现IConfigureOptions<TOptions>
接口,在方法中注册我们的配置类
ConfigureServices
。
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfigureOptions<ApplicationInsightsServiceOptions>, ConfigureApplicationInsightsServiceOptions>();
services.AddApplicationInsightsTelemetry();
}
public class ConfigureApplicationInsightsServiceOptions : IConfigureOptions<ApplicationInsightsServiceOptions>
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public ConfigureApplicationInsightsServiceOptions(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}
public void Configure(ApplicationInsightsServiceOptions options)
{
using var scope = _serviceScopeFactory.CreateScope();
var provider = scope.ServiceProvider;
var settings = provider.GetRequiredService<AppSettings>();
if (!settings.EnableTracking)
{
options.EnableQuickPulseMetricStream = false;
options.EnablePerformanceCounterCollectionModule = false;
options.EnableAppServicesHeartbeatTelemetryModule = false;
options.EnableAzureInstanceMetadataTelemetryModule = false;
options.EnableDependencyTrackingTelemetryModule = false;
options.EnableEventCounterCollectionModule = false;
options.EnableAdaptiveSampling = false;
options.EnableDebugLogger = false;
options.EnableHeartbeat = false;
options.EnableRequestTrackingTelemetryModule = false;
options.EnableAuthenticationTrackingJavaScript = false;
options.EnableDiagnosticsTelemetryModule = false;
}
}
}
我目前正在评估此模式,但我不确定 Application Insights 在我的应用程序中是否完全禁用。
解决方案
在基本示例中,无需构建服务提供者。大多数文档甚至都建议不要这样做。可以直接从配置中提取所需的设置。
public void ConfigureService(IServiceCollection services) {
var section = configuration.GetSection(nameof(AppSettings));
// Configure the services for IOptions injection
services.Configure<AppSettings>(section);
// Extract the settings from configuration explicitly as needed
AppSettings appSettings = section.Get<AppSettings>();
// Conditionally include the service using the settings
if (appSettings.EnableApplicationInsights) {
services.AddApplicationInsightsTelemetry();
}
//...
}
确实不需要涉及依赖类或使用自定义IConfigureOptions<TOptions>
来满足 Startup 中所需的条件
推荐阅读
- ios - dynamicMemberLoookup ExpressibleByStringLiteral 参数 swift
- vb.net - 以非列表方式向 DataTable 添加大量列?
- javascript - VueJS - V-for 在数据更新后不会重新渲染,需要刷新页面才能看到更改
- java - Spring Boot + Gradle:运行单个测试时采用 VM 选项
- html - html2canvas 图像在页面滚动时未完全呈现
- json - 我无法使用 ImportJSON 的解析选项
- c# - 如何停止和删除hangfire中的所有处理后台作业?
- javascript - 如何同时加载 magnific-popup 的“ajax 链接”和“ajax 链接页面内容”?
- python - 在 Python 中执行 http 请求的最快方法是什么
- matplotlib - height of colorbar in subplot (matplotlib)