-
เนื่องจากประสิทธิภาพที่จำกัดของเซิร์ฟเวอร์ ฉันพบว่าเนื่องจากการใช้ Castle + Nhibernate กระบวนการคอมไพล์ใหม่ของเซิร์ฟเวอร์หลังจากอัปเดตเว็บไซต์จึงใช้เวลานานเป็นพิเศษ บางครั้งใช้เวลานานกว่า 1 นาที แม้ว่าโปรแกรมเว็บที่เผยแพร่จะถูกคอมไพล์ด้วยก็ตาม ต่อไปนี้เป็นไลบรารีไดนามิกที่ใช้โดยเว็บ:
Castle.Core.dll
Castle.DynamicProxy2.dll
Castle.Facilities.AutomaticTransactionManagement.dll
Castle.Facilities.NHibernateIntegration.dll
Castle.MicroKernel.dll
Castle.Services.Transaction.dll
Castle.Windsor.dll
FredCK.FCKeditorV2.dll
Iesi.Collections.dll
log4net.dll
MySql.Data.dll/System.Data.SQLite.dll
NHibernate.dll
UrlRewritingNet.UrlRewriter.dll
ทุกครั้งที่โครงการเว็บของฉันได้รับการอัปเดตและ web.dll สร้างขึ้นหลังจากการคอมไพล์ใหม่ไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์ w3p จะรีสตาร์ทและ csc ไฟล์ในไดเรกทอรีเว็บของฉัน กระบวนการทั้งหมดนั้นยาวมากและทนไม่ได้
[ฉันสงสัยว่าพวกคุณมีข้อเสนอแนะที่ดีหรือไม่]
ต่อมา ฉันคิดว่าการใส่ไดนามิกไลบรารีข้างต้นลงใน GAC จะช่วยลดเวลาที่ต้องใช้ในการรีสตาร์ทหรือไม่ (แนวทางปฏิบัติได้พิสูจน์แล้วว่าไม่มีการเปลี่ยนแปลงที่ชัดเจน)
บทความนี้ไม่ได้แก้ปัญหาเดิม แต่เนื่องจากเกี่ยวข้องกับปัญหาในการอ้างอิงไลบรารีไดนามิกของบุคคลที่สามที่จัดเก็บไว้ใน GAC ใน asp.net ฉันจึงยังคงบันทึกไว้ (:-) นี่คือจุดเน้นของบทความนี้)
ไลบรารีไดนามิกข้างต้นทั้งหมดได้รับการลงนามแล้ว และกระบวนการใส่ไลบรารีเหล่านั้นลงใน GAC คือ:
1. ลงทะเบียนไดนามิกไลบรารีบุคคลที่สามใน GAC
gacutil -i Castle.Core.dll
gacutil -i Castle.DynamicProxy2.dll
gacutil -i Castle.Facilities.AutomaticTransactionManagement.dll
gacutil -i Castle.Facilities.NHibernateIntegration.dll
gacutil -i Castle.MicroKernel.dll
gacutil -i Castle.Services.Transaction.dll
gacutil -i Castle.Windsor.dll
gacutil -i FredCK.FCKeditorV2.dll
gacutil -i Iesi.Collections.dll
gacutil -i Intelligencia.UrlRewriter.dll
gacutil -i log4net.dll
gacutil -i MySql.Data.dll
gacutil -i NHibernate.dll
gacutil -i System.Data.SQLite.dll
gacutil -i UrlRewritingNet.UrlRewriter.dll
กระบวนการนี้ค่อนข้างง่าย โดยสามารถพบได้ gacutil ภายใต้ sdk ของ .net framework (แพ็คเกจการแจกจ่ายซ้ำ)
2. กำหนดวิธีที่เว็บโปรเจ็กต์อ้างอิงถึงไลบรารีไดนามิกของบุคคลที่สาม: อ้างอิง GAC โดยตรง
ปัญหาอีกประการหนึ่งที่พบในที่นี้คือ vs2005 ไม่สามารถอ้างอิงไลบรารีไดนามิกของบริษัทอื่นที่กำหนดไว้ใน GAC ได้ เว้นแต่จะทำการตั้งค่าต่อไปนี้:
สมมติว่าไลบรารีไดนามิกของบริษัทอื่นที่คุณกำหนดถูกจัดเก็บไว้ใน: c:3rdlibs
ปรับเปลี่ยนรีจิสทรี: HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFrameworkAssemblyFolders
เพิ่มรายการภายใต้โครงการนี้และชี้ไปที่ c:3rhlibs
ตอนนี้เราสามารถอ้างอิงไลบรารี GAC บุคคลที่สามในโครงการเว็บของเราได้แล้ว
3. คอมไพล์เว็บใหม่และแก้ไขข้อบกพร่อง:
ปัญหาแรก: ข้อผิดพลาดในการกำหนดค่า
ดู plaincopy ไปที่ clipboardprint หรือไม่
ข้อผิดพลาดในการกำหนดค่า
คำอธิบาย: มีข้อผิดพลาดเกิดขึ้นขณะประมวลผลไฟล์คอนฟิกูเรชันที่จำเป็นในการให้บริการคำร้องขอนี้ โปรดตรวจสอบรายละเอียดข้อผิดพลาดเฉพาะด้านล่างและแก้ไขไฟล์การกำหนดค่าอย่างเหมาะสม
ข้อความแสดงข้อผิดพลาดของ Parser: ไม่สามารถโหลดแฟ้มหรือแอสเซมบลี 'UrlRewritingNet.UrlRewriter' หรือการอ้างอิงอย่างใดอย่างหนึ่ง ระบบไม่พบไฟล์ที่ระบุ (web.config บรรทัด 50)
ข้อผิดพลาดแหล่งที่มา:
บรรทัดที่ 48:
บรรทัดที่ 49: <httpโมดูล>
บรรทัด 50: <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter"/>
ไฟล์ต้นฉบับ: web.config บรรทัด: 50
คำอธิบายข้อผิดพลาดในการกำหนดค่า: มีข้อผิดพลาดเกิดขึ้นขณะประมวลผลไฟล์การกำหนดค่าที่จำเป็นในการให้บริการคำขอนี้ โปรดตรวจสอบรายละเอียดข้อผิดพลาดเฉพาะด้านล่างและแก้ไขไฟล์การกำหนดค่าอย่างเหมาะสม
ข้อความแสดงข้อผิดพลาดของ Parser: ไม่สามารถโหลดแฟ้มหรือแอสเซมบลี 'UrlRewritingNet.UrlRewriter' หรือการอ้างอิงอย่างใดอย่างหนึ่ง ระบบไม่พบไฟล์ที่ระบุ (web.config บรรทัด 50)
ข้อผิดพลาดแหล่งที่มา:
บรรทัดที่ 48:
บรรทัดที่ 49: <httpโมดูล>
บรรทัด 50: <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter"/>
ไฟล์ต้นฉบับ: web.config บรรทัด: 50
แน่นอนว่าโครงการเว็บของเราไม่พบไลบรารีที่จัดเก็บไว้ใน GAC แล้ว ก่อนที่จะใส่ลงใน GAC ไลบรารีเหล่านี้จะถูกคอมไพล์และส่งออกไปยังไดเร็กทอรี web/bin ขณะนี้ไม่สามารถระบุตำแหน่งได้โดยอัตโนมัติ เราจึงสามารถแก้ไข web.config เพื่อระบุวิธีอ้างอิงไลบรารีได้:
ดู plaincopy ไปที่ clipboardprint หรือไม่
<การกำหนดค่า>
-
<รันไทม์>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly PartName = "log4net" fullName = "log4net รุ่น = 1.2.10.0 วัฒนธรรม =เป็นกลาง PublicKeyToken = 1b44e1d426115821"/>
<qualifyAssembly partName = "Castle.Windsor" fullName = "Castle.Windsor, เวอร์ชัน = 1.0.3.0, วัฒนธรรม =เป็นกลาง, PublicKeyToken = 407dd0808d44fbdc"/>
<qualifyAssembly PartName = "Castle.MicroKernel" fullName = "Castle.MicroKernel รุ่น = 1.0.3.0 วัฒนธรรม =เป็นกลาง PublicKeyToken = 407dd0808d44fbdc"/>
-
</assemblyBinding>
</รันไทม์>
</การกำหนดค่า>
<การกำหนดค่า>
-
<รันไทม์>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly PartName = "log4net" fullName = "log4net รุ่น = 1.2.10.0 วัฒนธรรม =เป็นกลาง PublicKeyToken = 1b44e1d426115821"/>
<qualifyAssembly partName = "Castle.Windsor" fullName = "Castle.Windsor, เวอร์ชัน = 1.0.3.0, วัฒนธรรม =เป็นกลาง, PublicKeyToken = 407dd0808d44fbdc"/>
<qualifyAssembly PartName = "Castle.MicroKernel" fullName = "Castle.MicroKernel รุ่น = 1.0.3.0 วัฒนธรรม =เป็นกลาง PublicKeyToken = 407dd0808d44fbdc"/>
-
</assemblyBinding>
</รันไทม์>
</การกำหนดค่า>
คอมไพล์ ดีบัก และรันอีกครั้ง
ข้อผิดพลาดที่สอง: ข้อผิดพลาดในการรวบรวม
ดู plaincopy ไปที่ clipboardprint หรือไม่
ข้อผิดพลาดของเซิร์ฟเวอร์ในแอปพลิเคชัน '/'
-------------------------------------------------- -------------------------------------------------- ----------------------------------
ข้อผิดพลาดในการรวบรวม
คำอธิบาย: มีข้อผิดพลาดเกิดขึ้นขณะรวบรวมทรัพยากรที่จำเป็นในการให้บริการคำร้องขอนี้ โปรดตรวจสอบรายละเอียดข้อผิดพลาดเฉพาะต่อไปนี้และแก้ไขซอร์สโค้ดอย่างเหมาะสม
ข้อความแสดงข้อผิดพลาดของคอมไพเลอร์: CS0012: พิมพ์ 'Castle.Windsor.IContainerAccessor' ถูกกำหนดไว้ในแอสเซมบลีที่ไม่ได้อ้างอิง ต้องเพิ่มการอ้างอิงถึงแอสเซมบลี "Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc"
ข้อผิดพลาดแหล่งที่มา:
[ไม่มีบรรทัดแหล่งที่มาที่เกี่ยวข้อง]
ไฟล์ต้นฉบับ: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaa.0.cs บรรทัด: 133
ข้อผิดพลาดของเซิร์ฟเวอร์ในแอปพลิเคชัน '/'
-------------------------------------------------- -------------------------------------------------- ----------------------------------
คำอธิบายข้อผิดพลาดในการรวบรวม: มีข้อผิดพลาดเกิดขึ้นระหว่างการรวบรวมทรัพยากรที่จำเป็นในการตอบสนองคำขอนี้ โปรดตรวจสอบรายละเอียดข้อผิดพลาดเฉพาะต่อไปนี้และแก้ไขซอร์สโค้ดอย่างเหมาะสม
ข้อความแสดงข้อผิดพลาดของคอมไพเลอร์: CS0012: พิมพ์ 'Castle.Windsor.IContainerAccessor' ถูกกำหนดไว้ในแอสเซมบลีที่ไม่ได้อ้างอิง ต้องเพิ่มการอ้างอิงถึงแอสเซมบลี "Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc"
ข้อผิดพลาดแหล่งที่มา:
[ไม่มีบรรทัดแหล่งที่มาที่เกี่ยวข้อง]
ไฟล์ต้นฉบับ: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaa.0.cs บรรทัด: 133
คราวนี้เป็นข้อผิดพลาดในการคอมไพล์ แต่ข้อความแสดงข้อผิดพลาดไม่ชัดเจนและไม่สามารถระบุเนื้อหาเฉพาะได้ในขณะนี้ แก้ไข web.config และเพิ่มส่วนการกำหนดค่า (คอมไพล์) ดังนี้
ดู plaincopy ไปที่ clipboardprint หรือไม่
<การกำหนดค่า>
<system.เว็บ>
-
<คอมไพล์ดีบัก = "true" />
-
</system.เว็บ>
</การกำหนดค่า>
<การกำหนดค่า>
<system.เว็บ>
-
<คอมไพล์ดีบัก = "true" />
-
</system.เว็บ>
</การกำหนดค่า>
การดีบักอีกครั้ง:
ดู plaincopy ไปที่ clipboardprint หรือไม่
ข้อผิดพลาดในการรวบรวม
คำอธิบาย: มีข้อผิดพลาดเกิดขึ้นขณะรวบรวมทรัพยากรที่จำเป็นในการให้บริการคำร้องขอนี้ โปรดตรวจสอบรายละเอียดข้อผิดพลาดเฉพาะต่อไปนี้และแก้ไขซอร์สโค้ดอย่างเหมาะสม
ข้อความแสดงข้อผิดพลาดของคอมไพเลอร์: CS0012: พิมพ์ 'Castle.Windsor.IContainerAccessor' ถูกกำหนดไว้ในแอสเซมบลีที่ไม่ได้อ้างอิง ต้องเพิ่มการอ้างอิงถึงแอสเซมบลี "Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc"
ข้อผิดพลาดแหล่งที่มา:
บรรทัด 134: }
บรรทัดที่ 135:
บรรทัด 136: ASP.global_asax ApplicationInstance ที่มีการป้องกัน {
บรรทัด 137: รับ {
บรรทัด 138: return ((ASP.global_asax)(this.Context.ApplicationInstance));
ไฟล์ต้นฉบับ: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaa.0.cs บรรทัด: 136
คำอธิบายข้อผิดพลาดในการรวบรวม: มีข้อผิดพลาดเกิดขึ้นระหว่างการรวบรวมทรัพยากรที่จำเป็นในการตอบสนองคำขอนี้ โปรดตรวจสอบรายละเอียดข้อผิดพลาดเฉพาะต่อไปนี้และแก้ไขซอร์สโค้ดอย่างเหมาะสม
ข้อความแสดงข้อผิดพลาดของคอมไพเลอร์: CS0012: พิมพ์ 'Castle.Windsor.IContainerAccessor' ถูกกำหนดไว้ในแอสเซมบลีที่ไม่ได้อ้างอิง ต้องเพิ่มการอ้างอิงถึงแอสเซมบลี "Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc"
ข้อผิดพลาดแหล่งที่มา:
บรรทัด 134: }
บรรทัดที่ 135:
บรรทัด 136: ASP.global_asax ApplicationInstance ที่มีการป้องกัน {
บรรทัด 137: รับ {
บรรทัด 138: return ((ASP.global_asax)(this.Context.ApplicationInstance));
ไฟล์ต้นฉบับ: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaa.0.cs บรรทัด: 136
ข้อความแสดงข้อผิดพลาดนี้สำคัญที่สุด:
ข้อความแสดงข้อผิดพลาดของคอมไพเลอร์: CS0012: พิมพ์ 'Castle.Windsor.IContainerAccessor' ถูกกำหนดไว้ในแอสเซมบลีที่ไม่ได้อ้างอิง ต้องเพิ่มการอ้างอิงถึงแอสเซมบลี "Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc"
แน่นอนว่าหลังจากที่เราแก้ไข web.config แล้ว บริการ iis จะรีสตาร์ทเว็บโปรเจ็กต์ปัจจุบันและคอมไพล์มัน สิ่งแรกที่ต้องคอมไพล์คือ global.asax.cs หนึ่งในตัวแปรที่เริ่มต้นอาจเป็นตัวแปรคงที่ วินด์เซอร์ถูกเรียก และ csc ไม่พบปราสาทแห่งนี้ วินด์เซอร์ ซึ่งเป็นกระบวนการที่ยุ่งยากจริงๆ
ความพยายามครั้งแรก: ในส่วนอ้างอิงของโครงการเว็บ ให้ตั้งค่า Castle.Windsor เดิมที เมื่อมีการอ้างอิงไลบรารีไดนามิกโดยตรง จะถูกส่งออกไปยังเว็บ/ถังพร้อมกัน หลังจากอ้างอิง GAC แล้ว เอาต์พุตนี้จะถูกยกเลิก ตั้งค่าเป็น "คัดลอกไปที่เครื่อง" แน่นอนว่าการคอมไพล์หลังจากการตั้งค่าจะส่งออกไฟล์นี้: Castle.Windsor ไปยัง web/bin ด้วยวิธีนี้ การดีบักสามารถผ่านไปได้เนื่องจากเขาพบไลบรารีแบบไดนามิกนี้
แต่นี่ไม่ได้คลายข้อสงสัยของเรา กล่าวคือ Assembly ที่กำหนดไว้ใน <runtime><assemblyBinding>... ...</assemblyBinding><runtime> ไม่ส่งผลกระทบต่อกระบวนการคอมไพล์ ดังนั้นจึงต้องใช้ในระหว่างกระบวนการคอมไพล์ มันคือภาคไหน?
ความพยายามครั้งที่สอง: คิดถึงส่วน (การคอมไพล์) ในครั้งแรก ตรวจสอบคำอธิบาย msdn และรู้ว่ามีคำจำกัดความของ <assemblies> ใน <compilation> เพิ่มการกำหนดค่าดังนี้:
ดู plaincopy ไปที่ clipboardprint หรือไม่
<คอมไพล์ดีบัก = "false">
<แอสเซมบลี>
<เพิ่มแอสเซมบลี = "Castle.Windsor เวอร์ชัน = 1.0.3.0 วัฒนธรรม =เป็นกลาง PublicKeyToken = 407dd0808d44fbdc"/>
</ชุดประกอบ>
</คอมไพล์>
<คอมไพล์ดีบัก = "false">
<แอสเซมบลี>
<เพิ่มแอสเซมบลี = "Castle.Windsor เวอร์ชัน = 1.0.3.0 วัฒนธรรม =เป็นกลาง PublicKeyToken = 407dd0808d44fbdc"/>
</ชุดประกอบ>
</คอมไพล์>
จากนั้นยกเลิก "คัดลอกไปยังท้องถิ่น" สำหรับ Castle.Windsor ในโครงการเว็บ คอมไพล์ใหม่และรัน
ทั้งหมดทำงานได้ดี
ณ จุดนี้ เราได้นำไลบรารีไดนามิกทั้งหมดที่บุคคลที่สามอ้างอิงมาไว้ใน GAC เรียบร้อยแล้ว