如何在不调用 Configure() 的情况下全局设置 HttpMessageHandler on Flurl 调用
How to set HttpMessageHandler on Flurl calls globally without calling Configure()
我正在构建一个供内部使用的小型库,它依赖于 Flurl 来处理所有传出 HTTP 调用。
我想为该库的使用者提供选择加入我们的 HTTP 调用跟踪基础结构的能力,如下所示:
Startup.cs:
...
public void ConfigureServices(IServiceCollection services)
{
....
services.AddTracing(options => ...);
....
}
...
我当前的 AddTracing()
实现如下所示:
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddTracing(this IServiceCollection services, Action<TracingOptions> configureOptions)
{
var tracingOptions = new TracingOptions();
configureOptions(tracingOptions);
// Make these options available in DI container
services.AddSingleton(tracingOptions);
FlurlHttp.Configure(settings =>
{
settings.HttpClientFactory = new TracingHttpClientFactory(tracingOptions.ApplicationName);
});
return services;
}
}
TracingHttpClientFactory
的当前实现如下所示:
public class TracingHttpClientFactory : DefaultHttpClientFactory
{
private readonly string _applicationName;
public TracingHttpClientFactory(string applicationName)
{
_applicationName = applicationName;
}
// override to customize how HttpMessageHandler is created/configured
public override HttpMessageHandler CreateMessageHandler()
{
var tracingHandler = new TracingHandler(_applicationName, base.CreateMessageHandler());
return tracingHandler;
}
}
这有效,但我面临的问题是 Configure()
的文档显示:只应在应用程序启动时调用一次。
因此,我通过添加跟踪(可选)“浪费”了对 Configure()
的调用。在使用tracing的场景下,我之后还需要调用Configure()
我可能需要在之后调用配置的示例在 Startup.cs:
...
public void ConfigureServices(IServiceCollection services)
{
....
// Configure() is being called inside AddTracing()
services.AddTracing(options => ...);
....
// This is a second call to Configure()
FlurlHttp.Configure(settings => {
var jsonSettings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
settings.JsonSerializer = new NewtonsoftJsonSerializer(jsonSettings);
});
}
...
要点 - AddTracing()
的每个消费者都应该能够按照他们认为合适的方式配置 Flurl。 AddTracing()
的要点是用一些额外的可选功能简单地“增强”Flurl。它并不意味着接管 Configure()
- 它意味着扩展它。
我一直在阅读文档 here,尽管有很多地方可以进行配置,但我无法找到一种方法来获取我的 TracingHandler
(这是一个 HttpMessageHander
) 进入每个请求而不调用 Configure()
某处。
我描述的场景是否有合适的实现?
“启动时调用一次”建议的原因是它涉及全局范围。如果您开始在许多不同的地方,可能是在不同的线程上(例如,在控制器操作方法中)弄乱全局设置,您最终可能会遇到奇怪的竞争条件和其他不可预测的行为。
在您的情况下,是的,您调用了 Configure
两次,但调用是连续的、不冲突的,并且在“启动”代码属于 ASP.NET 核心应用程序的地方正确完成.最重要的是,它们在使用 Flurl 进行任何调用之前就已完成。所以你在这里做的很好。
我正在构建一个供内部使用的小型库,它依赖于 Flurl 来处理所有传出 HTTP 调用。
我想为该库的使用者提供选择加入我们的 HTTP 调用跟踪基础结构的能力,如下所示:
Startup.cs:
...
public void ConfigureServices(IServiceCollection services)
{
....
services.AddTracing(options => ...);
....
}
...
我当前的 AddTracing()
实现如下所示:
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddTracing(this IServiceCollection services, Action<TracingOptions> configureOptions)
{
var tracingOptions = new TracingOptions();
configureOptions(tracingOptions);
// Make these options available in DI container
services.AddSingleton(tracingOptions);
FlurlHttp.Configure(settings =>
{
settings.HttpClientFactory = new TracingHttpClientFactory(tracingOptions.ApplicationName);
});
return services;
}
}
TracingHttpClientFactory
的当前实现如下所示:
public class TracingHttpClientFactory : DefaultHttpClientFactory
{
private readonly string _applicationName;
public TracingHttpClientFactory(string applicationName)
{
_applicationName = applicationName;
}
// override to customize how HttpMessageHandler is created/configured
public override HttpMessageHandler CreateMessageHandler()
{
var tracingHandler = new TracingHandler(_applicationName, base.CreateMessageHandler());
return tracingHandler;
}
}
这有效,但我面临的问题是 Configure()
的文档显示:只应在应用程序启动时调用一次。
因此,我通过添加跟踪(可选)“浪费”了对 Configure()
的调用。在使用tracing的场景下,我之后还需要调用Configure()
我可能需要在之后调用配置的示例在 Startup.cs:
...
public void ConfigureServices(IServiceCollection services)
{
....
// Configure() is being called inside AddTracing()
services.AddTracing(options => ...);
....
// This is a second call to Configure()
FlurlHttp.Configure(settings => {
var jsonSettings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
settings.JsonSerializer = new NewtonsoftJsonSerializer(jsonSettings);
});
}
...
要点 - AddTracing()
的每个消费者都应该能够按照他们认为合适的方式配置 Flurl。 AddTracing()
的要点是用一些额外的可选功能简单地“增强”Flurl。它并不意味着接管 Configure()
- 它意味着扩展它。
我一直在阅读文档 here,尽管有很多地方可以进行配置,但我无法找到一种方法来获取我的 TracingHandler
(这是一个 HttpMessageHander
) 进入每个请求而不调用 Configure()
某处。
我描述的场景是否有合适的实现?
“启动时调用一次”建议的原因是它涉及全局范围。如果您开始在许多不同的地方,可能是在不同的线程上(例如,在控制器操作方法中)弄乱全局设置,您最终可能会遇到奇怪的竞争条件和其他不可预测的行为。
在您的情况下,是的,您调用了 Configure
两次,但调用是连续的、不冲突的,并且在“启动”代码属于 ASP.NET 核心应用程序的地方正确完成.最重要的是,它们在使用 Flurl 进行任何调用之前就已完成。所以你在这里做的很好。