Deteksi tumpukan Xamarin HttpClient saat runtime

Dalam aplikasi Xamarin iOS saya dapat menentukan implementasi HttpClient mana yang akan digunakan saat runtime:

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

Namun pengaturan ini hanya mempengaruhi HttpClients yang dibuat menggunakan ctor default:

var client = new HttpClient()

Tetapi bagaimana jika saya ingin menambahkan beberapa intersepsi permintaan ke klien http saya dengan menyediakan DelegatingHandler khusus ke ctor? Saya kemudian akan menggunakan ctor lain:

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

Idealnya saat runtime saya perlu tahu httpHandler mana yang dipilih dalam pengaturan proyek waktu kompilasi agar myDel membungkusnya saat runtime. Bagaimana saya melakukannya?

UPD Saya dapat menemukan kode yang bertanggung jawab untuk memilih pengendali yang sesuai di sumber mono: https://github.com/mono/mono/blob/master/mcs/class/System.Net.Http/HttpClientEx.cs#L28 namun kelas RuntimeOptions bersifat internal dan saya hanya dapat menggunakannya melalui refleksi saat runtime. Namun dalam kasus ini, tautan Xamarin menghapus RuntimeOptions dari dll dalam mode rilis dan aplikasi mogok dalam rilis dan pembuatan adhoc tetapi tidak dalam debug. Adakah yang tahu apa yang terjadi pada RuntimeOptions di xamarin build yang mendukung linker sehingga saya dapat menggunakannya untuk mengetahui httphandler runtime?


person FreoN    schedule 15.06.2016    source sumber
comment
Jika memungkinkan, saya akan mendaftar untuk uji coba gratis di Universitas Xamarin dan ada kursus mengenai topik ini yang mungkin bisa sangat membantu. Kursusnya XAM150 REST Web Services dan menjelaskan banyak hal lebih baik daripada saya. Dari apa yang saya ingat dari kursus itu Anda dapat mengatur httpClienthandlers dalam kode vs menggunakan pengaturan proyek dan bertukar antara CFNetworkHandler dan NSUrlSessionHander sesuai kebutuhan berdasarkan DelegatingHandlers yang ingin Anda gunakan . Karena Anda melakukan ini dalam kode, Anda tahu pada saat run time HTTPClientHandler mana yang Anda instal ke HttpClient Anda.   -  person Bearcat9425    schedule 15.06.2016
comment
@ Bearcat9425 Ya, menurut saya sekarang Anda benar. Tentu saja saya dapat mengontrol penangan apa yang akan diteruskan ke DelegatingHandler saya sebagai innerHandler, saya hanya ingin tahu apakah ada kemampuan untuk menentukan penangan mana yang dipilih sebagai default dalam pengaturan proyek Xamarin untuk mencoba membuatnya konsisten di seluruh solusi dan misalnya menyuntikkannya penangan yang dipilih melalui Autofac atau apa pun ke HttpClient layanan saya.   -  person FreoN    schedule 15.06.2016
comment
Saya melihat di catatan itu saya tidak yakin.   -  person Bearcat9425    schedule 15.06.2016


Jawaban (1)


Jangan melawan linker - ia akan menghapusnya karena ini merupakan pengoptimalan ukuran agar dapat menggunakan penangan yang diperlukan saja.

Namun Anda masih dapat menggunakan refleksi di tempat lain, tempat yang tidak dapat dihapus oleh linker. Anda dapat melihat contohnya di contoh HttpClient. Inilah baris pentingnya:

typeof(HttpMessageInvoker).GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue (client).GetType ();
person poupou    schedule 16.06.2016
comment
Sejujurnya refleksi juga tidak aman ketika Anda menggunakan linker, karena linker tidak tahu apakah Anda akan menggunakan api pribadi/publik tertentu dalam waktu kompilasi karena nama anggota di-hardcode. Namun jawaban Anda paling cocok untuk semuanya. Ketika saya tidak tahu bagaimana internal HttpClient dibangun di bawah tenda, saya dapat membuat instance HttpClient dan merefleksikannya (dan dalam hal ini tidak ada yang dihapus oleh linker karena saya benar-benar menggunakan HttpClient dalam kode saya) untuk mendapatkan penangan internal. Tidak bersih tapi berfungsi, ya. - person FreoN; 16.06.2016
comment
Sayangnya, handlernya tidak diekspos (misalnya sebagai properti) oleh API publik. Bagaimanapun refleksi dapat aman dari tautan, Anda hanya perlu memastikan informasi tersebut tidak dapat dihapus (dengan kode Anda atau kode yang Anda panggil). Dalam hal ini handler tidak dapat dihapus jika Anda menggunakan HttpClient. Tentu saja ini tidak lebih aman daripada refleksi itu sendiri karena ia mendasarkan dirinya pada internal yang dapat berubah seiring waktu (tapi itu tidak ada hubungannya dengan linker itu sendiri). - person poupou; 16.06.2016