การตรวจจับ Xamarin HttpClient Stack ในรันไทม์

ในแอปพลิเคชัน Xamarin iOS ฉันสามารถระบุการใช้งาน HttpClient ที่จะใช้ในรันไทม์ได้:

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

อย่างไรก็ตาม การตั้งค่านี้มีผลกับ HttpClients ที่สร้างโดยใช้ ctor เริ่มต้นเท่านั้น:

var client = new HttpClient()

แต่ถ้าฉันต้องการเพิ่มการสกัดกั้นคำขอไปยังไคลเอนต์ http ของฉันโดยการจัดหา DelegatingHandler แบบกำหนดเองให้กับ ctor ฉันจะใช้ ctor อื่น:

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

ตามหลักการแล้วในรันไทม์ ฉันจำเป็นต้องรู้ว่า httpHandler ใดถูกเลือกในการตั้งค่าโปรเจ็กต์เวลาคอมไพล์ เพื่อให้ myDel ล้อมมันในรันไทม์ ฉันต้องทำอย่างไร?

UPD ฉันสามารถค้นหาโค้ดที่รับผิดชอบในการเลือกตัวจัดการที่เหมาะสมในแหล่งที่มาของโมโน: https://github.com/mono/mono/blob/master/mcs/class/System.Net.Http/HttpClientEx.cs#L28 อย่างไรก็ตาม คลาส RuntimeOptions เป็นแบบภายใน และฉันสามารถใช้ได้ผ่านการสะท้อนกลับในรันไทม์เท่านั้น ในกรณีนี้ อย่างไรก็ตาม ตัวเชื่อมโยงของ Xamarin จะดึง RuntimeOptions จาก dll ในโหมด release และแอปขัดข้องใน release และ adhoc builds แต่ไม่ได้อยู่ใน debug ไม่มีใครรู้ว่าจะเกิดอะไรขึ้นกับ RuntimeOptions ในบิลด์ xamarin ที่เปิดใช้งาน linker ดังนั้นฉันจึงสามารถใช้มันเพื่อค้นหา httphandler รันไทม์ได้


person FreoN    schedule 15.06.2016    source แหล่งที่มา
comment
หากเป็นไปได้ ฉันจะสมัครทดลองใช้งานฟรีที่มหาวิทยาลัย Xamarin และมีหลักสูตรในหัวข้อนี้ซึ่งอาจช่วยได้มาก หลักสูตร XAM150 REST Web Services และอธิบายสิ่งต่างๆ ได้ดีกว่าฉันมาก จากสิ่งที่ฉันจำได้จากหลักสูตรนั้น คุณสามารถตั้งค่า httpClienthandlers ในโค้ดเทียบกับการใช้การตั้งค่าโปรเจ็กต์ และสลับระหว่าง CFNetworkHandler และ NSUrlSessionHander ตามความจำเป็น โดยขึ้นอยู่กับ DelegatingHandlers ที่คุณต้องการใช้ . เนื่องจากคุณกำลังทำสิ่งนี้ในโค้ด คุณจะทราบ ณ รันไทม์ว่า HTTPClientHandler ใดที่คุณกำลังติดตั้งลงใน HttpClient ของคุณ   -  person Bearcat9425    schedule 15.06.2016
comment
@ Bearcat9425 ใช่แล้ว สำหรับฉันแล้วดูเหมือนว่าคุณพูดถูก แน่นอนว่าฉันสามารถควบคุมตัวจัดการที่จะส่งผ่านไปยัง DelegatingHandler ของฉันในฐานะ innerHandler ได้ ฉันแค่สงสัยว่ามีความสามารถในการกำหนดว่าตัวจัดการตัวใดที่ถูกเลือกเป็นค่าเริ่มต้นในการตั้งค่าโปรเจ็กต์ของ Xamarin เพื่อพยายามทำให้มันสอดคล้องกันในโซลูชันทั้งหมดและตัวอย่างเช่น ฉีดสิ่งนั้น ตัวจัดการที่เลือกผ่าน Autofac หรืออะไรก็ตามใน HttpClient ของบริการของฉัน   -  person FreoN    schedule 15.06.2016
comment
ฉันเห็นในบันทึกนั้นฉันไม่แน่ใจ   -  person Bearcat9425    schedule 15.06.2016


คำตอบ (1)


อย่าต่อสู้กับตัวเชื่อมโยง - มันกำลังลบมันออกเพราะมันเป็นการปรับขนาดให้เหมาะสมเพื่อให้สามารถใช้ตัวจัดการที่จำเป็นได้

อย่างไรก็ตาม คุณยังคงสามารถใช้การสะท้อนไปที่อื่นได้ ซึ่งเป็นจุดที่ตัวเชื่อมโยงไม่สามารถเอาออกได้ คุณสามารถดูตัวอย่างดังกล่าวได้ในตัวอย่าง HttpClient. นี่คือบรรทัดสำคัญ:

typeof(HttpMessageInvoker).GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue (client).GetType ();
person poupou    schedule 16.06.2016
comment
การสะท้อนที่พูดตรงไปตรงมาก็ไม่ปลอดภัยเช่นกันเมื่อคุณใช้ลิงเกอร์ เนื่องจากลิงเกอร์ไม่รู้ว่าคุณกำลังจะใช้ api ส่วนตัว/สาธารณะบางตัวในเวลาคอมไพล์หรือไม่ เพราะชื่อสมาชิกเป็นแบบฮาร์ดโค้ด อย่างไรก็ตาม คำตอบของคุณเหมาะสมที่สุด เมื่อฉันไม่รู้ว่าโครงสร้างภายในของ HttpClient ถูกสร้างขึ้นภายใต้ประทุนอย่างไร ฉันสามารถยกตัวอย่าง HttpClient และไตร่ตรองได้ (และในกรณีนี้ไม่มีตัวเชื่อมโยงใดถูกถอดออกเนื่องจากฉันใช้ HttpClient ในโค้ดของฉันจริงๆ) เพื่อรับตัวจัดการภายใน ไม่สะอาดแต่ใช้งานได้ใช่ - person FreoN; 16.06.2016
comment
น่าเสียดายที่ตัวจัดการไม่ได้ถูกเปิดเผย (เช่น คุณสมบัติ) โดย API สาธารณะ อย่างไรก็ตาม การสะท้อนกลับ สามารถ ปลอดภัยจากตัวเชื่อมโยง คุณเพียงแค่ต้องแน่ใจว่าข้อมูลนั้นไม่สามารถลบออกได้ (ด้วยรหัสของคุณหรือรหัสที่คุณเรียก) ในกรณีนี้ handler ไม่สามารถลบออกได้หากคุณใช้ HttpClient แน่นอนว่ามันไม่ได้ มากกว่า ปลอดภัยไปกว่าการสะท้อนกลับ เพราะมันขึ้นอยู่กับสิ่งภายในที่อาจเปลี่ยนแปลงได้ตลอดเวลา (แต่นั่นไม่เกี่ยวข้องกับตัวเชื่อมโยงเอง) - person poupou; 16.06.2016