ข้อดีของการใช้ไฟล์. dll ผ่านการเชื่อมโยงไฟล์. cs กับโปรเจ็กต์ (สำหรับคลาสตัวช่วย / วิธีการขยายทั่วไป)


38

ฉันมีโครงการตัวช่วยซึ่งฉันใช้ในแอปพลิเคชันทั้งหมดที่ฉันสร้าง มันมีวิธีการขยายและเรียนผู้ช่วยทั่วไปการควบคุม ฯลฯ ฉันอัปเดต / ขยายโครงการผู้ช่วยเป็นครั้งคราว เหล่านี้มักเป็นโครงการขนาดเล็กและไม่เกี่ยวข้องและฉันเป็นคนเดียวที่ทำงานกับพวกเขาทั้งหมด

ฉันลองสองวิธีในการใช้

  • เพิ่มไฟล์. cs โดยตรง (เพิ่มลิงค์) ไปยังแต่ละโครงการที่ฉันใช้
  • รวบรวมเป็น. dll และเพิ่มเป็นข้อมูลอ้างอิง

ฉันเห็นประโยชน์และข้อเสียของวิธีการเหล่านี้
คนแรก:

  • นั้นง่ายกว่าเนื่องจากคลาสตัวช่วยได้รับการคอมไพล์เป็นไฟล์ exe ดังนั้นฉันมักจะสามารถให้ไฟล์. exe เพียงไฟล์เดียวที่ใช้งานได้ดี เนื่องจากฉันเพิ่มเป็นลิงก์ฉันจึงมั่นใจได้ว่าเมื่อใดก็ตามที่ฉันสร้างโครงการใด ๆ ที่ใช้ตัวช่วยเหลือไฟล์ผู้ช่วยเหลือจะเป็นเวอร์ชันล่าสุด
  • ยิ่งง่ายขึ้นเพราะฉันสามารถแยกไฟล์เพื่อให้วิธีการขยายของฉันที่ทำงานได้ดีบน. NET 4.0 สามารถอ้างอิงแยกต่างหากจากวิธีที่ต้องใช้. NET 4.5 ซึ่งหมายความว่าแอปโดยรวมสามารถทำงานบน. NET 4.0 ได้
  • ช่วยให้การแก้จุดบกพร่องผ่านรหัสที่มีประโยชน์ทั้งหมดของเบรกพอยต์ ฯลฯ ฯลฯ ...
  • ดูเหมือนจะไม่ใช่ 'การปฏิบัติที่ดีที่สุด'

คนที่สอง:

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

ดังนั้นประโยชน์ที่แท้จริงของการใช้ไฟล์. dll ที่นี่คืออะไร โปรดทราบว่าฉันเป็นคนเดียวที่แก้ไขรหัสของแอปพลิเคชันทั้งหมดและไฟล์ตัวช่วย


นอกจากนี้เพื่อชี้แจง - แอปมักจะน้อยมากในขณะที่รหัสที่มีอยู่ในชั้นเรียนของผู้ช่วยนั้นเป็นเรื่องธรรมดาสำหรับพวกเขาทั้งหมด (การเปรียบเทียบสตริงแบบง่าย ๆ เส้นทางหรือการดำเนินงาน XML ฯลฯ )


จริงๆแล้วมีคนทำให้ฉันรู้ว่าตอนนี้มีตัวเลือกที่สาม เนื่องจากฉันมีรหัสตัวช่วยในโครงการ separte ฉันสามารถเพิ่มโครงการนี้เพื่อแก้ปัญหาของแต่ละแอปพลิเคชันของฉัน - ซึ่งทำงานเหมือนกับ 'Add as link' สำหรับไฟล์เดียวยกเว้นฉันเพิ่มเพียงโครงการเดียว ... แต่ ดังที่ Doc Brown สังเกตเห็นว่านี่จำเป็นต้องมีการเพิ่ม. dll ลงในโครงการต่อไป ...

อีกสิ่งหนึ่งที่ไม่ควรใช้ไฟล์ dll ก็คือความสามารถในการดีบั๊กผ่านคลาสตัวช่วย ...


3
คุณพูดถูกและฉันก็ทำเช่นนั้นเพราะมันช่วยในกรณีที่มีความต้องการ. NET สูงกว่า ... แต่ฉันไม่ชอบทำ ... ตัวติดตั้งสำหรับแอพ 40kb เป็นบิตของ overkill :)
Bartosz

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

2
เมื่อคุณเพิ่มโครงการในโซลูชันคุณยังต้องปรับใช้ DLL ของโครงการนี้ด้วยข้อเสียทั้งหมดที่คุณระบุไว้ข้างต้น
Doc Brown

2
@DocBrown - อึศักดิ์สิทธิ์คุณขวา :)
Bartosz

1
การลิงก์ไฟล์. cs หรือโปรเจ็กต์อาจมีข้อเสียเปรียบอื่น หากคุณกำลังใช้ไฟล์ที่ใช้ร่วมกันเหล่านี้ในหลายโครงการและอีกหนึ่งโครงการต้องเปลี่ยนการแบ่งไลบรารีที่ใช้ร่วมกันของคุณตอนนี้คุณต้องปรับโครงสร้างโครงการอื่นของคุณใหม่ การอ้างอิงที่กำลังป้องกันคุณจากการที่หากไม่มีเหตุผลสำหรับรหัสของคุณที่จะต้องมีตรรกะที่ปรับปรุง ฉันเป็นส่วนหนึ่งของทีมพัฒนาที่พบปัญหานี้เมื่อโครงการที่ใช้ร่วมกันเกี่ยวข้องกับสิ่งต่าง ๆ เช่นการรับรองความถูกต้องที่กำหนดเอง ลูกค้าต้องการลองเปลี่ยนแอพพลิเคชั่นใหม่และตอนนี้คุณต้องทำการไลบรารี่ทั่วไปของคุณ ใช้กำลังทำอย่างนั้น
Ellesedil

คำตอบ:


13

คุณเห็นข้อดีและข้อเสียส่วนใหญ่แล้ว การใช้ไฟล์ cs เป็นข้อมูลอ้างอิงนั้นมีน้ำหนักเบากว่าและจัดการได้ง่ายกว่า อย่างไรก็ตามฉันขอแนะนำให้ใช้วิธีนี้เฉพาะเมื่อcsไฟล์ของคุณมีอยู่ในตัวเองอย่างสมบูรณ์และไม่มีความต้องการสร้างพิเศษใด ๆ

ใช้ DLLs แยกต่างหาก

  • จะทำให้การอ้างอิงกับยูทิลิตี้หรือไลบรารีอื่น ๆ ชัดเจน (ตราบใดที่คุณไม่มีการพึ่งพาดังกล่าวมันจะทำงานได้ดี)

  • จะช่วยให้คุณสามารถกำหนดค่าการสร้างเฉพาะ (ตัวอย่างเช่นถ้าคลาสใช้งานได้ในการกำหนดค่า x86 หรือต้องการอย่างน้อย. NET 4.0 การกำหนดค่าการสร้างของแอสเซมบลีทำให้ข้อกำหนดนี้ชัดเจน)

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

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


ตกลงขอบคุณมาก - ดังนั้นฉันจะเข้าใจอย่างถูกต้องว่าตราบใดที่ผู้ช่วยของฉันไม่ได้อ้างอิงใด ๆ ที่กำลังภายนอกอื่น ๆ (มีรหัส. NET มาตรฐานเท่านั้น) มันไม่ได้เป็นสิ่งที่น่ารังเกียจที่จะเชื่อมโยงพวกเขา?
Bartosz

@Bartosz: ไม่มี DLLs ภายนอกและแต่ละคลาสตัวช่วยไม่ควรใช้คลาสตัวช่วยอื่นใดหรือคลาสตัวช่วยอื่นที่เก็บไว้ในไฟล์เดียวกัน ความซื่อสัตย์ในระดับหนึ่งคุณสามารถจัดการสถานการณ์ที่ผู้ช่วยคลาส A ต้องการผู้ช่วยคลาส B ที่จัดเก็บไว้ในไฟล์แยกต่างหาก แต่วิธีการนี้ใช้ไม่ได้ดี
Doc Brown

1
@PeterK - อ๋อและฉันก็ทำ :)
Bartosz

1
@whatsisname: ไม่ใช่ว่ามันไม่สามารถใช้งานได้ แต่ฉันก็ไม่ได้เสียงเหมือนการแก้ปัญหาซึ่งจะลดความซับซ้อนของสิ่งที่มากขึ้นเช่นหนึ่งซึ่งอาจทำให้เกิดปัญหาที่ไม่คาดคิด ;-)
หมอสีน้ำตาล

1
@Ozkan: ในสภาพแวดล้อมของเรามันเป็นเพียงการปรับใช้ xcopyกับการแชร์เครือข่ายบางส่วน (ด้วยขั้นตอนพิเศษบางอย่างสำหรับการสำรองข้อมูลเวอร์ชั่นเก่าและตรวจสอบให้แน่ใจว่าไม่มีใครใช้โปรแกรมในปัจจุบัน - ซึ่งทำได้โดยความพยายามในการเปลี่ยนชื่อโฟลเดอร์ มันรู้ที่กำลังจะถูกปรับใช้เพราะเราเข้ารหัสรายการ DLL ที่ต้องการลงในสคริปต์ - ไม่ต้องใช้เวทมนตร์ใด ๆ โซลูชันนี้ไม่สมบูรณ์ แต่เหมาะกับเราในกรณีส่วนใหญ่ยกเว้นโปรแกรมที่มีผู้ใช้หลายสิบคนใช้งานอย่างหนัก
Doc Brown

11

Dll มีประโยชน์เมื่อแอปพลิเคชันมีขนาดใหญ่และมีชิ้นส่วนที่ต้องการการอัปเดต แต่ไม่ใช่ทั้งแอปพลิเคชัน ดังนั้นหากคุณกำลังเขียน MS Word จะมีประโยชน์หากคุณมีรหัสตรวจสอบการสะกดคำใน DLL ที่สามารถอัปเดตได้โดยไม่ต้องอัปเดต MS Word ทั้งหมด หากสิ่งที่คุณเขียนเป็นแอพยูทิลิตี้ขนาดเล็ก (หรือชุดของแอพที่มีในตัวเองซึ่งเกิดขึ้นกับทุกคนใช้รหัสเดียวกัน) มันไม่ได้สร้างความแตกต่างมากนักว่ารหัสนั้นฝังอยู่ในแอพหรือไม่


2

คุณได้ข้อสรุปในคำถามของคุณฉันมีเพียงไม่กี่จุดที่จะเพิ่ม

Mono Optionsเป็นตัวอย่างที่ยอดเยี่ยมของแพ็คเกจ NuGet ที่ใช้วิธีการแรกเป็นอย่างดี

อีกทางเลือกหนึ่งถ้าคุณตัดสินใจที่จะใช้ DLLs คุณสามารถใช้เครื่องมือเช่นCosturaเพื่อฝังการอ้างอิงนั้นในปฏิบัติการของคุณเป็นทรัพยากรที่ฝังตัว หากต้องการใช้เพียงเพิ่มCostura.Fodyแพ็คเกจ:

Install-Package Costura.Fody

ที่จริงแล้วมีอีกสิ่งหนึ่ง - ด้วยการฝังโครงการหรือไฟล์ที่เพิ่มเป็นลิงก์คุณยังสามารถดีบักรหัสผ่านไฟล์ผู้ช่วยได้อย่างแข็งขัน ...
Bartosz

1
@ Bartosz ฉันคิดว่าคุณยังสามารถ debug "ตลอดทาง" โดยไม่มี "ไฟล์ helper" ตราบใดที่คุณมีไฟล์ pdb ที่ถูกต้อง
แซค

ฉันลองสิ่งที่ Costura และฉันชอบมันมาก!
Bartosz

2

ไม่ว่า dll จะเป็นประโยชน์มากขึ้นหรือไม่ขึ้นอยู่กับปัจจัยหลายประการ:

  1. ขนาดของรหัส (เมื่อรวบรวม)
  2. มีกี่ exes ที่ใช้
  3. คุณตั้งใจจะอัพเดทรหัสบ่อยแค่ไหน
  4. ไม่ว่าจะมี exes หรือไม่ก็ตั้งใจที่จะเก็บไว้ด้วยกันหรือแยกกันอยู่อย่างสมบูรณ์

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

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

นอกจากนี้หากคุณสร้างไฟล์เรียกใช้งานได้เพียงไม่กี่ไฟล์ขนาดของรหัสในแต่ละไฟล์ที่เรียกใช้อาจมีขนาดเล็กพอที่จะไม่เป็นปัญหา อย่างไรก็ตามยิ่ง executables ที่คุณใช้รหัสเดียวกันมากเท่าไรก็จะยิ่งมีประโยชน์มากขึ้นถ้ารหัสนั้นถูกย้ายเข้าไปใน dll

เป็นตัวอย่างที่ง่ายขึ้นสมมติว่าคลาสตัวช่วยของคุณรวบรวมข้อมูลได้ถึง 128 ไบต์ในไฟล์ exe แต่เมื่อย้ายไปที่ dll dll จะมีขนาด 512 ไบต์ หากคุณมีไฟล์เรียกทำงาน 3 ไฟล์คุณจะประหยัดพื้นที่ได้โดยใส่รหัสลงในไฟล์เรียกทำงาน อย่างไรก็ตามถ้าคุณมีไฟล์ประมวลผล 5 ไฟล์คุณจะอยู่ในจุดที่คุณจะดีกว่าถ้ามี dll เพราะพื้นที่ที่รวมกันถ่ายโดยโค้ด 5 ชุด (5 * 128 = 640 ไบต์) มากกว่าพื้นที่ที่ใช้ โดยมีรหัสใน dll (512 ไบต์)

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

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


1

ตัวเลือกที่สามของคุณเหมาะสมที่สุด (เพิ่มเป็นโครงการ "ไลบรารีคลาส" แยกต่างหากในโซลูชัน) เป็นการรวมข้อดีของวิธีการทั้งหมด:

  • "โครงการผู้ช่วยเหลือ" ของคุณทันสมัยอยู่เสมอในโครงการต่างๆ
  • คุณสามารถอ้างอิงรหัสของโครงการเมื่อคุณต้องการเห็นการเปลี่ยนแปลงอย่างรวดเร็ว
  • คุณสามารถสร้างมันขึ้นมาสำหรับรุ่น. NET ที่ถูกต้องในแต่ละครั้ง
  • คุณสามารถฝัง DLL ใน exe ได้ดังนั้นอย่ากังวลไปเลยว่าคุณสามารถมีส่วนร่วมในการสร้างได้

เราทำสิ่งนี้ตลอดเวลาและฉันไม่สามารถทำอะไรได้นอกจากแนะนำวิธีนี้

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


2
ฉันเห็นว่าเมื่อฉันเพิ่มเป็นโครงการไปยังโซลูชันและอ้างอิงโครงการนี้ในโครงการอื่น ๆ จากนั้นจะยังคงสร้างเป็น. dll แยกต่างหากแทนที่จะฝังตัว ... ฉันควรระบุอะไรบ้าง
Bartosz

1

ในฐานะนักพัฒนาฉันมักจะรวมการอ้างอิงของยูทิลิตี้การแก้ปัญหาไปยังแอปพลิเคชันของฉันเพราะมันช่วยให้ฉันแก้จุดบกพร่องรหัส (และจุดบกพร่องที่เป็นไปได้ในยูทิลิตี้ด้วย!) รวมถึงการเปลี่ยนแปลงใด ๆ

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

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