Assembly Binding redirect: อย่างไรและทำไม?


127

นี่ไม่ใช่คำถามที่เป็นปัญหา แต่เป็นคำถามเพื่อความเข้าใจทั่วไปเกี่ยวกับการทำงานของการเปลี่ยนเส้นทางการผูกแอสเซมบลี

แบบสอบถาม

  1. เหตุใดการเปลี่ยนเส้นทางที่มีผลผูกพันจึงแสดงเฉพาะเวอร์ชันหลักและไม่ใช่หมายเลขรองสร้างและแก้ไข
  2. เวอร์ชันเก่าและใหม่จะเปลี่ยนแปลงเฉพาะเมื่อมีการเปลี่ยนแปลงในเวอร์ชันหลักหรือไม่?

    <dependentAssembly>
        <assemblyIdentity name="FooBar"  
                          publicKeyToken="32ab4ba45e0a69a1"  
                          culture="en-us" />  
    
        <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />  
    </dependentAssembly>

อาจเป็นเวอร์ชันใดก็ได้ไม่ใช่เฉพาะเวอร์ชันหลัก ตัวอย่างเช่น:oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"
Evk

@Evk: ตัวอย่างทั้งหมดที่ฉันเห็นแสดงเฉพาะเวอร์ชันหลักเท่านั้น
Nikhil Agrawal

4
นี่เป็นเพียงตัวอย่างและไม่มีที่ไหนระบุว่าเป็นวิธีเดียวที่เป็นไปได้
Evk

คำตอบ:


166

เหตุใดจึงจำเป็นต้องมีการเปลี่ยนเส้นทางที่มีผลผูกพัน สมมติว่าคุณมีแอปพลิเคชัน A ที่อ้างอิงไลบรารี B และไลบรารี C ของเวอร์ชัน 1.1.2.5 ด้วย ในทางกลับกันไลบรารี B ยังอ้างอิงไลบรารี C แต่เป็นเวอร์ชัน 1.1.1.0 ตอนนี้เรามีข้อขัดแย้งเนื่องจากคุณไม่สามารถโหลดแอสเซมบลีเดียวกันเวอร์ชันต่างๆที่รันไทม์ได้ ในการแก้ไขข้อขัดแย้งนี้คุณอาจใช้การเปลี่ยนเส้นทางการเชื่อมโยงโดยปกติจะเป็นเวอร์ชันใหม่ (แต่สามารถใช้กับเวอร์ชันเก่าได้เช่นกัน) คุณทำได้โดยการเพิ่มต่อไปนี้ไปยังแฟ้ม app.config ของการประยุกต์ใช้ภายใต้configuration > runtime > assemblyBindingส่วน (ดูที่นี่เพื่อดูตัวอย่างไฟล์ config เต็ม):

<dependentAssembly>
    <assemblyIdentity name="C"  
                      publicKeyToken="32ab4ba45e0a69a1"  
                      culture="en-us" />  

    <bindingRedirect oldVersion="1.1.1.0" newVersion="1.1.2.5" />  
</dependentAssembly>

คุณยังสามารถระบุช่วงของเวอร์ชันที่จะแมปได้:

<bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.2.5" />  

ตอนนี้ไลบรารี B ซึ่งรวบรวมโดยอ้างอิงถึง C ของเวอร์ชัน 1.1.1.0 จะใช้ C ของเวอร์ชัน 1.1.2.5 ในขณะรันไทม์ แน่นอนคุณควรตรวจสอบให้แน่ใจว่าไลบรารี C สามารถใช้งานร่วมกันได้แบบย้อนกลับหรืออาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิด

คุณสามารถเปลี่ยนเส้นทางไลบรารีเวอร์ชันใดก็ได้ไม่ใช่เฉพาะเวอร์ชันหลัก


ไฟล์เหล่านี้ไปอยู่ในส่วนใดและอยู่ในส่วนใด ใครช่วยกรุณาให้ลิงค์ไปยังแหล่งที่มาเช่น MSDN หรือคล้ายกันเพื่อใช้อ้างอิง จำไว้ว่าผู้คนจะเชื่อมโยงไปถึงบทความ SO Q / A ของคุณจากทั่วทุกมุมของเครื่องมือค้นหาและการอ้างอิงเป็นสิ่งสำคัญ ฉันมีเพื่อนร่วมงานคนหนึ่งบอกให้ฉัน "เพิ่มการเปลี่ยนเส้นทางแอสเซมบลีไปยังไฟล์ exe ของคุณ" ก่อนที่จะไปพักร้อนเป็นเวลาหนึ่งสัปดาห์และฉันก็มาถึงที่นี่และในขณะที่คำตอบนี้ดูดีมาก แต่ก็ขาดบริบทและการอ้างอิง
tpartee

คำถามที่ถูกต้อง @tpartee ฉันได้แก้ไขคำตอบแล้ว (รอการตรวจสอบจากเพื่อน) เพื่อรวมส่วนการกำหนดค่าและลิงก์ไปยังdocs.microsoft.com/en-us/dotnet/framework/configure-apps/…
Kobus Smit

1
@AlexanderDerck ในไฟล์ config ของแอปพลิเคชัน A - ไม่มีผลใด ๆ (เท่าที่ฉันทราบ) ในไฟล์ config ของไลบรารียกเว้นบางทีเมื่อไลบรารีนี้เป็นไลบรารีทดสอบหน่วยและ "ดำเนินการ" ในบางแง่โดยนักวิ่งทดสอบหน่วย
Evk

1
@AlexanderDerck มีคำถามสองสามสัปดาห์ที่ผ่านมาโดยมีการโหวตเพิ่มจำนวนมากและได้รับรางวัลซึ่งถามอย่างนั้น แต่ไม่มีใครสามารถให้คำตอบที่น่าเชื่อถือได้ - stackoverflow.com/q/48377474/5311735
Evk

1
@CodeEngine publicKeyToken ระบุแอสเซมบลี C. เฉพาะแอสเซมบลีที่เซ็นชื่อเท่านั้นที่มีโทเค็นคีย์สาธารณะที่ระบุตัวตน นี่คือคำถามที่เกี่ยวข้องเกี่ยวกับวิธีค้นหาโทเค็นนั้นเนื่องจากคุณมีแอสเซมบลี: stackoverflow.com/q/3045033/5311735
Evk

56

เราพบปัญหาเกี่ยวกับการเปลี่ยนเส้นทางการผูกสำหรับ NewtonSoft.Json เราค้นหาเวอร์ชันของไฟล์ในคุณสมบัติไฟล์ win 10 "9.0.1.19813" ค้นหาหมายเลขและการเปลี่ยนเส้นทางยังคงล้มเหลว ตรวจสอบเพิ่มเติมและพบว่าเรากำลังดูเวอร์ชันไฟล์ไม่ใช่เวอร์ชันแอสเซมบลี ดังนั้นฉันสงสัยว่ามีคนเข้าใจผิดว่า File Version (ซึ่งเปลี่ยนแปลงบ่อย) และ Assembly version (ซึ่งคุณมองไม่เห็นใน windows 10 File Explorer) หากต้องการดูเวอร์ชันประกอบของ dll คุณสามารถเรียกใช้สิ่งนี้ใน powershell แทนที่ชื่อ dll ด้วยชื่อที่คุณต้องการค้นหาเวอร์ชัน

[Reflection.AssemblyName]::GetAssemblyName('C:\development\bin\Newtonsoft.Json.dll').Version

ผลลัพธ์ข้างต้นคือ

Major  Minor  Build  Revision

-----  -----  -----  --------

9      0      0      0

ดูข้อมูลอ้างอิง:

ฉันจะดูแอสเซมบลี. NET ใน Windows Vista และใหม่กว่าได้อย่างไร (WIndows 7, 2008)

https://support.microsoft.com/en-nz/help/556041

ใส่คำอธิบายภาพที่นี่


12
โหวตเพิ่มความแตกต่างระหว่างเวอร์ชันไฟล์และเวอร์ชันแอสเซมบลี !!
mrid
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.