แชร์คลาส C# จากไลบรารีคลาสที่อ้างอิงผ่านไลบรารีอื่น

ฉันกำลังสร้างคลาสไลบรารี (MyLib) ซึ่งมีคลาสสาธารณะ A คลาสนั้นระบุวิธีการสาธารณะ M ที่ส่งคืนอินสแตนซ์ของคลาส B จากไลบรารีคลาสภายนอก (ExtLib)

ในการใช้ MyLib.A.M() ผู้ใช้ที่จะใช้ไลบรารีคลาสของฉันจะต้องอ้างอิงทั้ง MyLib และ ExtLib

คำถามของฉันคือ เป็นไปได้ไหมที่จะทำให้คลาส ExtLib.B สามารถเข้าถึงได้โดยตรงผ่าน MyLib (เช่น MyLib.B) ดังนั้นผู้ใช้จะไม่ต้องอ้างอิงทั้งสองไลบรารี แต่มีเพียง MyLib เท่านั้น


person STremblay    schedule 13.04.2016    source แหล่งที่มา
comment
ผู้ใช้จะสามารถเข้าถึงประเภทภายนอกได้อย่างไรหากพวกเขาไม่ได้อ้างอิงถึงประเภทเหล่านั้น   -  person Wjdavis5    schedule 13.04.2016
comment
ไม่ มันเป็นไปไม่ได้   -  person Jcl    schedule 13.04.2016
comment
คุณสามารถโหลดแอสเซมบลี ExtLib ได้โดยใช้ Reflection   -  person Gosha_Fighten    schedule 13.04.2016
comment
@Gosha_Fighten หรือคุณสามารถปล่อยประเภทในรันไทม์ได้ แต่ฉันไม่คิดว่านั่นคือสิ่งที่ OP ขอ: ถ้าเขาไม่มีประโยชน์สำหรับ B (เช่นใน: ในลักษณะที่ปลอดภัยต่อการพิมพ์) จริง ๆ แล้วเขา ไม่ต้องการการอ้างอิง ExtLib   -  person Jcl    schedule 13.04.2016
comment
คุณอาจลองทำสิ่งนี้: stackoverflow.com/questions/1829531/   -  person Mike Cheel    schedule 13.04.2016
comment
ใช้ ILMerge สำหรับสิ่งนี้   -  person Greg Ferreri    schedule 13.04.2016
comment
@MikeCheel จริง ๆ แล้ว ILMerge อาจเป็นวิธีแก้ปัญหาที่ดีที่สุดในสถานการณ์นี้ ความเป็นไปได้อีกอย่างหนึ่งคือการสร้าง wrapper แบบเต็มรอบ B วัตถุ แต่นั่นก็ค่อนข้างไม่สมเหตุสมผลหากความตั้งใจคือ เพื่อหลีกเลี่ยงการอ้างอิง (การอ้างอิงที่ไลบรารีหลักมีอยู่)   -  person Jcl    schedule 13.04.2016
comment
นอกจากนี้ ขึ้นอยู่กับว่าคุณเป็นคนขี้กลัวแค่ไหนและประเภทของแอสเซมบลีที่คุณสามารถถอดรหัสเปิดแอสเซมบลีของบุคคลที่สามในรูปแบบ JustCompile ถอดรหัสและยกโค้ดที่คุณต้องการ ฉันเคยทำมาก่อนในโอกาสที่หายาก =)   -  person Mike Cheel    schedule 13.04.2016
comment
@MikeCheel ILMerge จะสร้างชุดประกอบอื่น ดังนั้นหากมีการเปลี่ยนแปลงใน ExtLib จะต้องรวมแอสเซมบลีที่มีอยู่ใหม่อีกครั้ง ฉันคิดว่าเป็นทางเลือกที่ดีกว่า คุณสามารถสำรวจคุณสมบัติ B ทั้งหมดในเวลา JITing และคอมไพล์คุณสมบัติใหม่หากมีการเพิ่มเข้าไป แต่ในอีกด้านหนึ่ง ควรมีการใช้งานอินเทอร์เฟซในแอสเซมบลี MyLib ที่เปิดเผยคุณสมบัติใหม่ ดังนั้น MyLib ก็ควรเปลี่ยนเช่นกัน   -  person Gosha_Fighten    schedule 13.04.2016


คำตอบ (1)


คุณควรยอมรับว่าผู้ใช้ของคุณควรอ้างอิงชุดประกอบของคุณและชุดประกอบที่รองรับ

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

นอกจากนี้ยังมีคำถามเรื่องลิขสิทธิ์และการอนุญาตให้ใช้สิทธิอีกด้วย หากคุณเขียนชุดประกอบสนับสนุนด้วย ฉันเดาว่าคุณไม่น่าจะมีปัญหาเลย มิฉะนั้น การรวมชุดสนับสนุนเข้ากับชุดของคุณเองอย่างน้อยที่สุดอาจทำให้ผู้เขียนชุดนั้นขมวดคิ้วได้ ถ้าไม่ได้รับอนุญาตโดยสิ้นเชิง

ตัวเลือกที่น่ารังเกียจอีกประการหนึ่งอาจเป็นการส่งคืนออบเจ็กต์ dynamic จาก API ของแอสเซมบลีของคุณแทนที่จะเป็นประเภทที่ประกาศในแอสเซมบลีที่รองรับ แน่นอนว่าสิ่งนี้จะมีผลกระทบต่อประสิทธิภาพที่เป็นไปได้ และจะลบล้างความปลอดภัยของประเภทเวลาคอมไพล์ที่เป็นไปได้ ซึ่งอาจเป็นประโยชน์ตามปกติของการใช้ภาษาเช่น C# แต่มันก็สามารถทำได้

หากคุณทนไม่ได้กับความคิดที่ผู้ใช้เพิ่มการอ้างอิงไปยังไลบรารีที่สนับสนุน ตัวเลือกที่เหมาะสมจากมุมมองด้านวิศวกรรมซอฟต์แวร์คือการเปลี่ยน API ของแอสเซมบลีของคุณเพื่อไม่ให้ส่งคืนประเภทจากไลบรารีที่สนับสนุน พวกเขายังคงต้องการแอสเซมบลีนั้น ณ รันไทม์หากคุณใช้งาน แต่อย่างน้อยโค้ดของผู้ใช้ก็ไม่ต้องการการอ้างอิงที่ชัดเจน แต่ API ของคุณจะส่งกลับประเภทที่แอสเซมบลีของคุณประกาศและรวมประเภทของแอสเซมบลีที่รองรับ ซึ่งอาจปรับเปลี่ยนอินเทอร์เฟซของประเภทเหล่านั้น (การลบสมาชิกที่ไม่จำเป็นออก เพิ่มส่วนขยายใหม่ ฯลฯ) เพื่อให้เหมาะกับความต้องการของผู้ใช้ของคุณดีขึ้น ด้วยวิธีดังกล่าว ประเภทของแอสเซมบลีที่รองรับจะถูกซ่อนจากมุมมอง ดังนั้นจึงไม่จำเป็นต้องมีการอ้างอิงที่ชัดเจนจากแอสเซมบลีของผู้ใช้ของคุณ


IMHO ควรสังเกตว่าผู้ใช้ของคุณอ้างอิงถึงแอสเซมบลีอื่น ๆ มากมายที่แอสเซมบลีของคุณขึ้นอยู่กับอยู่แล้ว เช่น ถ้าไม่มีอะไรอย่างอื่น อย่างน้อยก็แอสเซมบลี .NET ต่างๆ จริงอยู่ สิ่งเหล่านี้จำนวนมากจำเป็นสำหรับโค้ด .NET ใดๆ ที่จะทำงานได้ ดังนั้นโปรเจ็กต์ของผู้ใช้จะมีการอ้างอิงเหล่านี้อยู่แล้ว แต่ยังคงแสดงถึงการอ้างอิงแอสเซมบลีเพิ่มเติม แอสเซมบลี .NET ที่ไม่ใช่ค่าเริ่มต้นอื่นๆ อาจจำเป็นหรือไม่จำเป็น ขึ้นอยู่กับว่าแอสเซมบลีของคุณใช้อะไรและส่งคืนรหัสของผู้ใช้ ไม่ว่าเรื่องประเภทนี้จะค่อนข้างเป็นเรื่องธรรมดาและไม่ใช่สิ่งที่เราควรสละเวลาจำนวนมากเพื่อพยายามหลีกเลี่ยง

ความจริงก็คือว่าจะต้องมีชุดประกอบรองรับในขณะใช้งานอยู่แล้ว ดังนั้นจึงดูเหมือนไม่ยากนักที่จะกำหนดให้แอสเซมบลีนั้นอ้างอิงโดยโปรเจ็กต์ของผู้ใช้เอง แอสเซมบลีอ้างอิงที่ประกาศประเภทโค้ดของตัวเองนั้นขึ้นอยู่กับวิธีการทำงานของ .NET สู้มันทำไม? ปัญหาที่น่าสนใจคืออะไรที่อาจกระตุ้นให้ใช้ความพยายามอย่างแท้จริงเพื่อหลีกเลี่ยงการอ้างอิงพิเศษนี้โดยโครงการของผู้ใช้

person Peter Duniho    schedule 14.04.2016
comment
ฉันจะตอบคำถามของคุณ อะไร ... ปัญหาคือ ... กระตุ้นให้ ... พยายามหลีกเลี่ยงการอ้างอิงนี้ คำตอบคือง่าย ๆ การมอบหมายโรงเรียนโดยมีข้อจำกัดที่กำหนด (หลังจากนั้น) โดยที่ชุดประกอบ A ควรใช้อินเทอร์เฟซชุดประกอบ B เท่านั้น และชุดประกอบ B ใช้อินเทอร์เฟซชุดประกอบ C เท่านั้น อย่างไรก็ตาม ฉันได้ออกแบบแอสเซมบลี C แล้วเพื่อให้บางคลาสมีประโยชน์กับทั้งแอสเซมบลี A และ B ก่อนที่จะได้รับแจ้งถึงข้อจำกัดดังกล่าว ดังนั้นฉันจึงมองหาวิธีเปลี่ยนชื่อคลาสเหล่านั้นจาก C และทำให้พวกเขาดูเหมือนเป็นของ B - person STremblay; 15.04.2016
comment
อา. งานโรงเรียน? คำตอบนั้นง่ายมาก: ห่อประเภทของชุดประกอบที่รองรับไว้ในประเภทของชุดประกอบของคุณเอง (เช่น ตัวเลือกที่สามที่ผมแนะนำด้านบน) ข้อจำกัดดังกล่าวเป็นไปตามอำเภอใจอยู่แล้ว ซึ่งบังคับใช้ด้วยเหตุผลทางวิชาการ ไม่มีเหตุผลที่จะต้องเสียเวลามองหาวิธีแก้ปัญหาที่ฉลาดไปกว่านี้อีกแล้ว (นอกจากนี้ ยังเป็นที่ถกเถียงกันอยู่ว่าการใช้ ilmerge จะเป็นไปตามข้อจำกัดที่กำหนดหรือไม่ เนื่องจากจะเทียบเท่ากับการนำชุดประกอบที่รองรับออกจากสมการทั้งหมด หรือไม่เปลี่ยนการรับแสงของประเภทและชุดประกอบ ขึ้นอยู่กับว่าเราจะมองอย่างไร มัน.) - person Peter Duniho; 15.04.2016
comment
ขอบคุณ ฉันจะดำเนินการต่อด้วย wrapper นั่นเป็นความคิดแรกของฉัน แต่ก็สงสัยว่ามีกลไกการนำเข้าแบบรวมบางประเภทที่สามารถรวมส่วนหนึ่งของแอสเซมบลีเข้ากับอีกอันหนึ่งได้โดยอัตโนมัติ ดูเหมือนว่าคำตอบคือไม่ ดังนั้นฉันจะไปกับกระดาษห่อ! - person STremblay; 15.04.2016