IHttpContextAccessor替代方法,用于访问IHostedService的作用域IServiceProvider

时间:2019-02-28 19:49:18

标签: c# asp.net-core .net-core azure-application-insights

我有一个使用.net core 2.2运行的IHostedService的实现,并且想要复制IHttpContextAccessor(但仅用于使用范围限定的IServiceProvdier,我将其称为{{1} }),并且遇到了问题。

要求IRequestServicesAccessor必须是一个Singleton(如IRequestServicesAccessor),但仍有权访问当前请求的作用域IHttpContextAccessor。这似乎是可能的,因为我试图仅复制IServiceProvider,但是在将IHttpContextAccessor设置为一个值后,AsyncLocal<>似乎会立即将其自身设置为null,因此它总是被视为{{ 1}}。

这是我的null实现的副本

IRequestServicesAccessor

我需要这个的原因是因为我正在使用Azure的Application Insights,尤其是 public interface IRequestServicesAccessor { IServiceProvider ServiceProvider { get; set; } } public class ManualRequestServicesAccessor : IRequestServicesAccessor { //This accessor is a tweaked copy of HttpContextAccessor private static readonly AsyncLocal<ServiceProviderHolder> serviceProviderCurrent = new AsyncLocal<ServiceProviderHolder>(); public IServiceProvider ServiceProvider { get { return ManualRequestServicesAccessor.serviceProviderCurrent.Value?.ServiceProvider; } set { ServiceProviderHolder holder = ManualRequestServicesAccessor.serviceProviderCurrent.Value; if (holder != null) { // Clear current ServiceProvider trapped in the AsyncLocals, as its done. holder.ServiceProvider = null; } if (value != null) { // Use an object indirection to hold the ServiceProvider in the AsyncLocal, // so it can be cleared in all ExecutionContexts when its cleared. ManualRequestServicesAccessor.serviceProviderCurrent.Value = new ServiceProviderHolder { ServiceProvider = value }; } } } private class ServiceProviderHolder { public IServiceProvider ServiceProvider; } } 。从我阅读的所有内容中,如果您想将TelemetryClient上下文/属性更改为使用TelemetryClient,并在需要当前请求范围的情况下使用ITelemetryInitializer,因为IHttpContextAccessor是单例。但是对于ITelemetryInitializer,没有IHostedService。所以我需要类似的东西。另外,我需要尝试使用其他路由而不使用IHttpContextAccessor

这是我的服务的工作方式:

  • 启动时,它会为网络请求(例如微服务通信)设置侦听器
  • 在检索消息时,我创建了一个新的IServiceProvider范围,并完整处理了请求并发送了响应(非常类似于http请求,但没有http)
  • 这些消息可能需要很长时间才能处理,并且可能同时有数百条消息。
  • 每个请求在其来自何处(多租户)都有不同的上下文,并且需要在ITelemetryInitializer / TelemetryClient上标记信息

任何帮助都会很棒。谢谢

0 个答案:

没有答案