จุดเริ่มต้นที่แท้จริงในรันไทม์ .NET เกิดขึ้นในคลาสและอินเทอร์เฟซที่ไม่มีเอกสาร (การแปล: แน่นอนคุณสามารถใช้ Reflector เพื่อดู J) มีคนน้อยมากยกเว้น Microsoft ที่รู้เกี่ยวกับอินเทอร์เฟซเหล่านี้และพวก Microsoft ที่พวกเขาไม่กระตือรือร้น พูดคุยเกี่ยวกับรายละเอียดเหล่านี้ พวกเขาเชื่อว่ารายละเอียดการใช้งานเหล่านี้มีประโยชน์เพียงเล็กน้อยสำหรับนักพัฒนาที่ใช้ ASP.NET ในการพัฒนาแอปพลิเคชัน
กระบวนการของผู้ปฏิบัติงาน (ASPNET_WP.EXE ใน IIS5, W3WP.EXE ใน IIS6) โฮสต์รันไทม์ .NET และ ISAPI DLL ซึ่ง (กระบวนการของผู้ปฏิบัติงาน) เรียกอินเทอร์เฟซขนาดเล็กที่ไม่มีการจัดการของวัตถุ COM และท้ายที่สุดก็ส่งการเรียกไปยังคลาส ISAPIRuntime ในอินสแตนซ์ (คำอธิบายประกอบ: ข้อความต้นฉบับเป็นคลาสย่อยอินสแตนซ์ของคลาส ISAPIRuntime แต่คลาส ISAPIRuntime เป็นคลาสที่ปิดผนึก ซึ่งผู้เขียนสงสัยว่าเป็นข้อผิดพลาดทางเสมียน หรือคลาสย่อยในที่นี้ไม่ได้หมายถึงคลาสย่อย) รายการลงในรันไทม์คือ คลาสที่ไม่มีเอกสารนี้ใช้อินเทอร์เฟซ IISAPIRuntime (สำหรับข้อกำหนดผู้โทร อินเทอร์เฟซนี้เป็นอินเทอร์เฟซ COM) อินเทอร์เฟซ COM พื้นฐานนี้ใช้ IUnknown เป็นอินเทอร์เฟซที่กำหนดไว้ล่วงหน้าที่ขยายจาก ISAPI ไปยัง ASP.NET รูปที่ 3 แสดง IISAPIRuntime อินเทอร์เฟซและลายเซ็นการโทร (โดยใช้เครื่องมือ .NET Reflector ที่ยอดเยี่ยมของ Lutz Roeder http://www.aisto.com/roeder/dotnet/) นี่เป็นวิธีที่ดีในการสำรวจวิธีการทีละขั้นตอนนี้
รูปที่ 3 - หากคุณต้องการเจาะลึกเข้าไปในอินเทอร์เฟซนี้ ให้เปิด Reflector แล้วชี้ไปที่ System.Web.Hosting namespace ลิงก์ที่ชี้ไปที่ ISAPI ECB ตัวชี้ที่มีการจัดการ ECB นี้ประกอบด้วยความสามารถในการเข้าถึงอินเทอร์เฟซ ISAPI ที่สมบูรณ์ที่ใช้ในการรับคำขอและส่งการตอบสนองกลับไปยัง IIS
อินเทอร์เฟซ IISAPIRuntime ทำหน้าที่เป็นจุดเชื่อมต่อระหว่างโค้ดที่ไม่มีการจัดการที่ขยายจาก ISAPI และ ASP.NET (เกี่ยวข้องโดยตรงใน IIS6) (ผ่านเนมไปป์ใน IIS5) หากคุณดูภายในคลาสนี้ คุณจะพบฟังก์ชัน ProcessRequest พร้อมด้วยลายเซ็นต่อไปนี้:
[return: MarshalAs(UnmanagedType.I4)]
int ProcessRequest([In] IntPtr ecb,
[In, MarshalAs(UnmanagedType.I4)] int useProcessModel);
พารามิเตอร์ ecb คือ ISAPI Extension Control Block (Extention Control Block) ซึ่งถูกส่งผ่านไปยังฟังก์ชัน ProcessRequest เป็นทรัพยากรที่ไม่มีการจัดการ ฟังก์ชันนี้รับ ECB เป็น อินเทอร์เฟซอินพุตและเอาต์พุตพื้นฐาน ใช้กับออบเจ็กต์คำขอและการตอบสนอง ISAPI ECB มีข้อมูลคำขอระดับต่ำทั้งหมด เช่น ตัวแปรเซิร์ฟเวอร์ สตรีมอินพุตสำหรับตัวแปรแบบฟอร์ม และสตรีมเอาต์พุตสำหรับการเขียนข้อมูลกลับไปยังไคลเอ็นต์ โดยพื้นฐานแล้วการอ้างอิง ecb จะมีให้ ฟังก์ชันการทำงานทั้งหมดสำหรับการเข้าถึงทรัพยากรที่สามารถเข้าถึงได้โดยคำขอ ISAPI ProcessRequest คือจุดเริ่มต้นและจุดออกสำหรับทรัพยากรนี้ (ecb) ไปยังโค้ดที่ได้รับการ
จัดการ กระบวนการของผู้ปฏิบัติงานหรือเธรด IIS แต่ ECB จะยังคงพร้อมใช้งานตลอดอายุของคำขอปัจจุบัน ECB มีกลไกในการแจ้งให้ ISAPI ทราบว่าคำขอได้รับการประมวลผลแล้ว (ผ่านวิธี ecb.ServerSupportFunction) (คำอธิบายประกอบ: เพิ่มเติม สำหรับข้อมูลเพิ่มเติม ดูบทความเกี่ยวกับการพัฒนาส่วนขยาย ISAPI) ซึ่งทำให้ ECB ได้รับการเผยแพร่ วิธีการประมวลผลแบบอะซิงโครนัสนี้จะเผยแพร่เธรดของผู้ปฏิบัติงาน ISAPI ทันทีและส่งผ่านการประมวลผลไปยังเธรดแยกต่างหากที่จัดการโดย ASP.NET
ได้รับการอ้างอิงถึง ecb และ ใช้ภายในเพื่อรับข้อมูลเกี่ยวกับคำขอปัจจุบัน เช่น ตัวแปรเซิร์ฟเวอร์และข้อมูล POST นอกจากนี้ยังส่งคืนข้อมูลไปยังเซิร์ฟเวอร์ ecb ยังคงสามารถเข้าถึงได้ (คงอยู่) จนกว่าคำขอจะเสร็จสมบูรณ์หรือหมดเวลาด้วยวิธีนี้ สื่อสารกับมันต่อไปจนกว่าการประมวลผลคำขอจะเสร็จสิ้น เอาต์พุตจะถูกเขียนไปยังสตรีมเอาท์พุต ISAPI (โดยใช้ ecb.WriteClient()) และคำขอจะเสร็จสมบูรณ์ ส่วนขยาย ISAPI จะได้รับแจ้งว่าการประมวลผลคำขอเสร็จสมบูรณ์และเผยแพร่ ECB การใช้งานนี้มีประสิทธิภาพมาก เนื่องจากคลาส .NET เป็นเพียงตัวห่อหุ้ม "บาง" ที่มีประสิทธิภาพและไม่ได้รับการจัดการ
การโหลด .NET - ย้อนกลับไปจากที่นี่กันดีกว่า
: ฉันจะข้ามขั้นตอนนี้ไป โหลดรันไทม์ .NET นี่คือสิ่งที่คลุมเครือเล็กน้อย ฉันไม่พบเอกสารใด ๆ เกี่ยวกับกระบวนการนี้ และเนื่องจากเรากำลังพูดถึงโค้ดเนทิฟ จึงไม่มีวิธีที่ดีในการถอดรหัส ISAPI DLL และ คิดออก (โค้ดที่โหลดรันไทม์ .NET)
สิ่งที่ดีที่สุดที่ฉันสามารถทำได้คือเมื่อส่วนขยาย ISAPI ได้รับคำขอแรกสำหรับส่วนขยายที่แมปกับ ASP.NET งาน กระบวนการจะโหลดรันไทม์ .NET เมื่อรันไทม์มีอยู่ รหัสที่ไม่มีการจัดการสามารถขออินสแตนซ์ของ ISAPIRuntime สำหรับไดเร็กทอรีเสมือนที่ระบุได้ หากไม่มีอยู่ ไดเร็กทอรีเสมือนแต่ละอันมีโดเมนแอปพลิเคชันของตัวเอง ( AppDomain) เมื่อแอปพลิเคชันอิสระ (อ้างอิงถึงโปรแกรม ASP.NET) เริ่มต้นแล้ว ISAPIRuntime มีอยู่ในโดเมนแอปพลิเคชันเสมอจากกระบวนการเริ่มต้น (คำอธิบายประกอบ: ควรอ้างอิงถึงการสร้างอินสแตนซ์ของ ISAPIRuntime) ดูเหมือนว่าจะผ่าน COM ซึ่งทำได้เนื่องจากวิธีอินเทอร์เฟซถูกเปิดเผยเป็นวิธีการเรียก
COM คำขอไดเรกทอรีเสมือนมา ฟังก์ชัน System.Web.Hosting.AppDomainFactory.Create() ถูกเรียกเพื่อสร้างอินสแตนซ์ของ ISAPIRuntime ซึ่งจะเริ่มกระบวนการเริ่มต้นของแอปพลิเคชัน การเรียกนี้จะได้รับชนิดของแอปพลิเคชัน ชื่อโมดูล และข้อมูลไดเรกทอรีเสมือน ซึ่งใช้โดย ASP.NET เพื่อสร้างโดเมนแอปพลิเคชันและเริ่มโปรแกรม ASP.NET สำหรับไดเร็กทอรีเสมือนนี้ (หมายเหตุประกอบ: ข้อความต้นฉบับคือออบเจ็กต์ที่ได้รับ HttpRuntime นี้ แต่ HttpRuntime เป็นคลาสที่ปิดสนิท ซึ่งสงสัยว่า ที่เป็นข้อผิดพลาดในข้อความต้นฉบับ) จะถูกสร้างขึ้นในโดเมนแอปพลิเคชันใหม่ แต่ละไดเร็กทอรีเสมือน (นั่นคือ แอปพลิเคชัน ASP.NET ถูกโฮสต์) ถูกโฮสต์ในโดเมนแอปพลิเคชันที่แยกต่างหาก และจะถูกโหลดเฉพาะเมื่อ ASP ที่ระบุเท่านั้น มีการร้องขอโปรแกรม .NET ส่วนขยาย ISAPI จัดการอินสแตนซ์ของวัตถุ HttpRuntime เหล่านี้และกำหนดเส้นทางคำขอภายในตามไดเรกทอรีเสมือนที่ร้องขอไปยังวัตถุ HttpRuntime ที่ถูกต้อง
รูปที่ 4 - คำขอ ISAPI ถูกส่งไปยังไปป์ไลน์ HTTP ของ ASP.NET โดยใช้คลาสที่ไม่มีเอกสาร อินเทอร์เฟซ และการเรียกวิธีการจากโรงงานจำนวนมาก แต่ละแอปพลิเคชันเว็บ/ไดเร็กทอรีเสมือนจะทำงานในโดเมนแอปพลิเคชันของตัวเอง และผู้เรียก (คำอธิบายประกอบ: ISAPI DLL) จะรักษาข้อมูลอ้างอิง ไปยังอินเทอร์เฟซ IISAPIRuntime เพื่อทริกเกอร์การประมวลผลคำขอ ASP.NET