运行时 Xamarin HttpClient 堆栈检测

Posted

技术标签:

【中文标题】运行时 Xamarin HttpClient 堆栈检测【英文标题】:Xamarin HttpClient Stack detection in runtime 【发布时间】:2016-06-15 17:15:44 【问题描述】:

在 Xamarin ios 应用程序中,我可以指定在运行时使用哪个 HttpClient 实现:

https://developer.xamarin.com/guides/cross-platform/macios/http-stack/

但是这个设置只影响使用默认 ctor 构造的 HttpClients:

var client = new HttpClient()

但是,如果我想通过向 ctor 提供自定义 DelegatingHandler 来为我的 http 客户端添加一些请求拦截怎么办?然后我将使用另一个 ctor:

var myDel = new MyDel(RUNTIME_HANDLER_GOES_HERE);
var client = new HttpClient(myDel);

理想情况下,在运行时我需要知道在编译时项目设置中选择了哪个 httpHandler,以便 myDel 将其包装在运行时。我该怎么做?

UPD 我能够在 mono 的源代码中找到负责选择适当处理程序的代码:https://github.com/mono/mono/blob/master/mcs/class/System.Net.Http/HttpClientEx.cs#L28 但是 RuntimeOptions 类是内部的,我只能通过运行时的反射来使用它。但是在这种情况下,Xamarin 的链接器在发布模式下从 dll 中剥离 RuntimeOptions,并且应用程序在发布和临时构建中崩溃,但在调试中没有。有谁知道在启用链接器的 xamarin 构建中 RuntimeOptions 会发生什么,所以我可以利用它来找出运行时 httphandler?

【问题讨论】:

如果可能的话,我会在 Xamarin 大学注册一个免费试用版,并且有一个关于这个主题的课程可能会有很大帮助。它的课程 XAM150 REST Web 服务,它比我更好地解释了一些事情。根据我从该课程中记得的内容,您可以在代码中设置 httpClienthandlers 与使用项目设置,并根据您想要使用的 DelegatingHandlers 在 CFNetworkHandler 和 NSUrlSessionHander 之间进行交换.由于您在代码中执行此操作,因此您在运行时就知道要安装哪个 HTTPClientHandler 到您的 HttpClient。 @Bearcat9425 是的,现在在我看来你是对的。我当然可以控制将哪些处理程序作为 innerHandler 传递给我的 DelegatingHandler,我只是想知道是否有能力确定在 Xamarin 的项目设置中选择哪个处理程序作为默认处理程序,以尝试使其在整个解决方案中保持一致,例如注入通过 Autofac 或其他任何方式选择处理程序进入我的服务的 HttpClient。 我在那个纸条上看到我不确定。 【参考方案1】:

不要与链接器对抗 - 它正在删除它,因为它是一种大小优化,能够只使用所需的处理程序。

但是,您仍然可以在其他地方使用反射,这是链接器无法删除的地方。您可以在我们的HttpClient sample 中看到这样的示例。这是重要的一行:

typeof(HttpMessageInvoker).GetField("_handler", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue (client).GetType ();

【讨论】:

坦率地说,当您使用链接器时,反射也不安全,因为链接器不知道您是否会在编译时使用某些私有/公共 api,因为成员名称是硬编码的。但是,您的答案最适合。当我不知道 HttpClient 的内部结构是如何在引擎盖下构建的时,我可以实例化 HttpClient 并反射(在这种情况下,链接器不会剥离任何内容,因为我实际上在我的代码中使用了 HttpClient)它以获得内部处理程序。不干净但有效,是的。 很遗憾,处理程序没有被公共 API 公开(例如作为属性)。但是反射可以对链接器安全,您只需要确保信息不能被删除(通过您的代码或您调用的代码)。在这种情况下,如果您使用的是 HttpClient,则无法删除 handler。当然,它并不比反射本身安全,因为它基于可能随时间变化的内部结构(但这与链接器本身无关)。

以上是关于运行时 Xamarin HttpClient 堆栈检测的主要内容,如果未能解决你的问题,请参考以下文章

当 API 关闭时,Xamarin 表单依赖注入 HttpClient 超时不起作用

Xamarin - 在 .Net 标准库中使用 httpClient

Xamarin HTTPClient 突然无法获取/发布

在 HttpClient 异常上显示 AlertDialog (Xamarin Android)

调试器在解析 Rest API 响应 HttpClient、Xamarin Forms 时停止

Xamarin Native Android HttpClient,它位于哪里?