Ưu điểm của việc sử dụng các tệp dll so với việc liên kết các tệp .cs với các dự án (đối với các lớp trợ giúp / phương thức mở rộng chung của riêng tôi)


38

Tôi có một dự án trợ giúp mà tôi sử dụng trong tất cả các ứng dụng mà tôi tạo. Nó chứa một số phương thức mở rộng và một loạt các lớp trình trợ giúp chung, các điều khiển, v.v. Tôi thỉnh thoảng cập nhật / mở rộng dự án trình trợ giúp. Đây thường là những dự án nhỏ và không liên quan, và tôi là người duy nhất làm việc trên tất cả chúng.

Tôi đã thử hai cách tiếp cận để sử dụng nó

  • thêm tệp .cs trực tiếp (Thêm dưới dạng liên kết) vào từng dự án nơi tôi sử dụng chúng
  • biên dịch nó dưới dạng dll và thêm nó làm tài liệu tham khảo

Tôi thấy một số lợi ích và hạn chế của các phương pháp này.
Cái đầu tiên:

  • đơn giản hơn, vì các lớp của trình trợ giúp được biên dịch vào tệp exe, do đó tôi thường có thể dễ dàng cung cấp chỉ một tệp .exe duy nhất sẽ hoạt động tốt. Vì tôi thêm dưới dạng liên kết, tôi có thể khá chắc chắn rằng bất cứ khi nào tôi xây dựng bất kỳ dự án nào sử dụng trình trợ giúp, các tệp trợ giúp sẽ là phiên bản mới nhất.
  • thậm chí còn đơn giản hơn, vì tôi có thể tách các tệp để các phương thức mở rộng của tôi chạy tốt trên .NET 4.0 có thể được tham chiếu riêng với các tệp yêu cầu .NET 4.5, có nghĩa là toàn bộ ứng dụng có thể chạy trên .NET 4.0
  • Cho phép gỡ lỗi thông qua mã, với tất cả các lợi ích của điểm dừng, v.v ...
  • dường như không phải là 'thực hành tốt nhất'

Cái thứ hai:

  • dường như là cách tiếp cận đúng, nhưng:
  • yêu cầu tôi cung cấp một tập tin dll riêng biệt, vì một số lý do khó khăn hơn cho người dùng (họ có xu hướng chia sẻ các chương trình của tôi mà không có chương trình, sau đó gặp sự cố khi khởi động)
  • vì nó được biên dịch thành một tệp duy nhất, nó sẽ yêu cầu phiên bản .NET cao nhất - nhiều người dùng của tôi không có .NET 4.5 và chỉ một số thành phần của lớp trình trợ giúp của tôi yêu cầu điều này, có nghĩa là tôi có thể buộc một số người cập nhật hệ thống của họ mà không có lý do
  • Tôi cũng cần đảm bảo rằng bất cứ khi nào tôi cập nhật bất kỳ chương trình nào của mình, tôi cũng sẽ cung cấp tệp dll - mặc dù tôi không biết liệu nó có bị thay đổi kể từ phiên bản trước hay không (có thể là vậy, nhưng nó có thể cũng có thể là cùng một phiên bản). Tôi không thể thấy một cách đơn giản để xác định rằng, mà không theo dõi phiên bản lắp ráp, đó là công việc bổ sung. Hiện tại, khi tôi cập nhật các chương trình của mình, tôi chỉ cung cấp exe được cập nhật và tôi muốn giữ cho nó cấu hình nhỏ và thấp.

Vì vậy, lợi ích thực sự cho việc sử dụng tập tin tại đây là gì? Xin lưu ý rằng tôi là người duy nhất chỉnh sửa mã của tất cả các ứng dụng và tệp trợ giúp.


Ngoài ra, để làm rõ - các ứng dụng thường rất ít, trong khi mã chứa trong các lớp của trình trợ giúp hoàn toàn chung cho tất cả chúng (một số so sánh chuỗi đơn giản, đường dẫn hoặc hoạt động XML, v.v.)


Thật ra, có ai đó khiến tôi nhận ra rằng có một lựa chọn thứ ba. Khi tôi có mã trình trợ giúp trong một dự án separte, tôi có thể thêm dự án này vào các giải pháp của từng ứng dụng riêng biệt của mình - hoạt động giống như 'Thêm dưới dạng liên kết' cho các tệp duy nhất, ngoại trừ tôi chỉ thêm một dự án duy nhất ... Nhưng như được chú ý bởi Doc Brown, điều này về cơ bản có nghĩa là dll sẽ cần phải được thêm vào dự án ...

Tuy nhiên, một điều nữa có lợi cho việc không sử dụng các tệp dll là khả năng gỡ lỗi thông qua lớp người trợ giúp một cách chủ động ...


3
Bạn nói đúng, và tôi thậm chí đang làm điều đó, vì nó giúp trong trường hợp yêu cầu .NET cao hơn ... Nhưng tôi không thích làm điều đó ... Một trình cài đặt cho ứng dụng 40kb là một chút quá mức :)
Bartosz

3
Chà, bạn luôn có thể sử dụng một cái gì đó như Costura , nó là một công cụ để hợp nhất các DLL. Bạn có thể hợp nhất tất cả các phụ thuộc vào EXE, giữ một tệp duy nhất và cho phép bạn sử dụng bất kỳ thư viện cần thiết nào. Điều này có thể được tự động hóa cho quá trình xây dựng, để đơn giản.
Kroltan

2
Khi bạn thêm một dự án vào một giải pháp, bạn vẫn phải triển khai DLL của dự án này, với tất cả các nhược điểm bạn đã liệt kê ở trên.
Doc Brown

2
@DocBrown - tào lao thần thánh, bạn nói đúng :)
Bartosz

1
Liên kết các tệp .cs hoặc dự án có thể có một nhược điểm khác. Nếu bạn đang sử dụng các tệp được chia sẻ này trong nhiều dự án và một dự án yêu cầu thay đổi đột phá đối với các thư viện dùng chung của bạn, thì bây giờ bạn cần phải cấu trúc lại các dự án khác của mình. Các dll tham chiếu sẽ bảo vệ bạn khỏi điều đó nếu không có lý do nào để mã của bạn yêu cầu logic cập nhật. Tôi đã từng là một phần của các nhóm phát triển gặp phải vấn đề này khi các dự án được chia sẻ liên quan đến những thứ như xác thực tùy chỉnh. Khách hàng muốn thử thay đổi cho một ứng dụng mới và bây giờ bạn cần phiên bản thư viện chung của mình bằng cách nào đó. Sử dụng dlls làm điều đó.
Ellesedil

Câu trả lời:


13

Bạn đã phát hiện ra hầu hết các ưu và nhược điểm. Sử dụng tệp cs làm tài liệu tham khảo thực sự nhẹ hơn và thường dễ quản lý hơn. Tuy nhiên, tôi khuyên bạn chỉ nên sử dụng phương pháp này khi các cstệp của bạn hoàn toàn khép kín và không có bất kỳ yêu cầu xây dựng đặc biệt nào.

Sử dụng các DLL riêng biệt

  • sẽ làm cho các phụ thuộc vào các tiện ích hoặc thư viện khác trở nên rõ ràng (miễn là bạn không có các phụ thuộc đó, nó sẽ hoạt động tốt)

  • sẽ cho phép bạn xác định các cấu hình xây dựng cụ thể (ví dụ: nếu một lớp chỉ hoạt động trong cấu hình x86 hoặc cần ít nhất .NET 4.0, cấu hình xây dựng của lắp ráp làm cho yêu cầu này rõ ràng).

Vì vậy, đặc biệt nếu bạn có nhiều thành phần đơn lớp, độc lập, sử dụng tham chiếu đến các tệp là tốt, nhưng nếu bạn có các thành phần tham chiếu các thành phần khác hoặc yêu cầu xây dựng cụ thể, tôi khuyên bạn nên sử dụng DLL.

Để giảm thiểu các vấn đề với việc quản lý nhiều DLL riêng biệt, bạn có thể tạo gói trình cài đặt hoặc sử dụng ILMerge , có thể nhúng một tập hợp các cụm vào một tệp thực thi. Trong môi trường của chúng tôi, chúng tôi xử lý vấn đề khác nhau, bằng cách sử dụng tập lệnh triển khai cho mỗi ứng dụng. Kịch bản lệnh này đảm bảo tất cả các DLL cần thiết luôn được gửi đến sản xuất khi bản phát hành ứng dụng mới được xuất bản.


Ok, cảm ơn rất nhiều - vì vậy, tôi có hiểu chính xác không, miễn là các lớp trợ giúp của tôi không tham chiếu bất kỳ dll bên ngoài nào khác (chỉ chứa mã .NET tiêu chuẩn), đó không phải là một sự ghê tởm khi chỉ liên kết chúng?
Bartosz

@Bartosz: không có DLL bên ngoài và mỗi lớp trình trợ giúp không nên sử dụng bất kỳ lớp trình trợ giúp nào khác, hoặc chỉ các lớp trình trợ giúp khác được lưu trữ trong cùng một tệp. Thành thật mà nói, ở một mức độ nào đó, bạn có thể quản lý tình huống trong đó lớp người trợ giúp A cần lớp người trợ giúp B được lưu trữ trong một tệp riêng biệt, nhưng cách tiếp cận này không có quy mô tốt.
Doc Brown

1
@PeterK. - vâng, và tôi đã làm :)
Bartosz

1
@whatsisname: không phải cái này không thể hoạt động. Tuy nhiên, với tôi nó không giống như một giải pháp đơn giản hóa mọi thứ, giống như một giải pháp có thể gây ra sự cố không mong muốn ;-)
Doc Brown

1
@Ozkan: trong môi trường của chúng tôi, đây chỉ là triển khai xcopy cho một số chia sẻ mạng (với một số bước bổ sung để sao lưu phiên bản cũ và đảm bảo không có ai sử dụng chương trình hiện tại - điều này đạt được bằng cách cố gắng đổi tên thư mục triển khai trước). Nó biết dlls nào sẽ triển khai bởi vì chúng tôi mã hóa danh sách các DLL cần thiết vào tập lệnh - không có phép thuật nào đằng sau nó. Giải pháp này không hoàn hảo, nhưng hoạt động với chúng tôi trong hầu hết các trường hợp, ngoại trừ các chương trình được sử dụng nhiều bởi hàng tá người dùng.
Doc Brown

11

DLL rất tiện lợi khi một ứng dụng lớn và có những phần yêu cầu cập nhật, nhưng không phải toàn bộ ứng dụng. Vì vậy, nếu bạn đang viết MS Word, sẽ rất hữu ích khi có mã kiểm tra chính tả trong một DLL có thể được cập nhật mà không phải cập nhật toàn bộ MS Word. Nếu những gì bạn đang viết là một ứng dụng tiện ích nhỏ (hoặc một loạt các ứng dụng độc lập xảy ra với tất cả sử dụng cùng một mã) thì sẽ không có nhiều khác biệt cho dù mã đó có được nhúng trong (các) ứng dụng hay không.


2

Bạn đã tóm tắt khá nhiều trong câu hỏi của bạn, tôi chỉ có một vài điểm để thêm.

Mono Options là một ví dụ tuyệt vời về gói NuGet sử dụng phương pháp đầu tiên rất tốt.

Ngoài ra, nếu bạn quyết định sử dụng các dll, bạn có thể sử dụng các công cụ như Costura để nhúng tham chiếu đó vào tệp thực thi của mình dưới dạng tài nguyên được nhúng. Để sử dụng nó chỉ cần thêm Costura.Fodygói:

Install-Package Costura.Fody

Trên thực tế, có một điều nữa - với dự án nhúng hoặc tệp được thêm dưới dạng liên kết, bạn cũng có thể chủ động gỡ lỗi mã thông qua tệp trợ giúp ...
Bartosz

1
@Bartosz Tôi nghĩ bạn vẫn có thể gỡ lỗi "mọi cách" mà không cần "tệp trợ giúp", miễn là bạn có tệp pdb chính xác.
Zack

Tôi đã thử điều Costura và tôi thực sự thích nó!
Bartosz

2

Việc một dll có lợi hơn hay không phụ thuộc vào một số yếu tố:

  1. Kích thước của mã (khi biên dịch).
  2. Có bao nhiêu exes sử dụng nó.
  3. Tần suất bạn dự định cập nhật mã.
  4. Có hay không các exes được dự định giữ lại với nhau hoặc tồn tại hoàn toàn riêng biệt.

Mục đích của một thư viện chia sẻ là lấy mã chung cho nhiều tệp thực thi và tập trung hóa nó để tất cả các tệp thực thi chia sẻ một bản sao. Điều này nhằm tiết kiệm không gian và làm cho mã dễ cập nhật hơn.

Nếu số lượng mã trong lớp trình trợ giúp của bạn rất nhỏ, có thể không đáng để chuyển nó sang một dll vì chi phí của mã nằm trong một dll có thể chống lại lợi ích tiết kiệm không gian của việc tập trung hóa nó.

Ngoài ra, nếu bạn chỉ tạo một vài tệp thực thi, kích thước của mã trong mỗi tệp thực thi có thể đủ nhỏ để không gây ra sự cố. Tuy nhiên, càng có nhiều tệp thực thi bạn sử dụng cùng một mã, thì càng có lợi khi chuyển mã vào một dll.

Như một ví dụ đơn giản, giả sử lớp trình trợ giúp của bạn biên dịch thành 128 byte trong tệp exe, nhưng khi được chuyển sang một dll, dll là 512 byte. Nếu bạn chỉ có 3 tệp thực thi, bạn sẽ tiết kiệm không gian bằng cách bao gồm mã trong các tệp thực thi. Tuy nhiên, nếu bạn có 5 tệp thực thi, thì bạn sẽ có điểm tốt hơn khi có một dll vì không gian kết hợp chiếm 5 bản sao của mã (5 * 128 = 640 byte) nhiều hơn không gian được sử dụng bằng cách có mã trong một dll (512 byte).

Bây giờ hãy nói ví dụ bạn tìm thấy một lỗi trong mã trợ giúp của bạn. Nếu bạn đã biên dịch tất cả các tệp thực thi của mình với mã được nướng, bạn phải biên dịch lại mọi tệp thực thi duy nhất và sau đó phân phối lại các phiên bản được biên dịch lại. Nếu bạn biên dịch mã thành một dll, bạn sẽ chỉ phải biên dịch lại và phân phối lại một dll và lỗi sẽ tự động được sửa cho tất cả các tệp thực thi sử dụng nó.

Cuối cùng, đối với một chương trình để tìm một dll, nó phải biết nơi để tìm dll. Nếu bạn đang giữ tất cả các tệp thực thi của mình cùng nhau, bạn có thể đặt dll vào cùng một thư mục và tất cả chúng sẽ tìm thấy nó ngay lập tức. Nếu bạn cố tình giữ chúng tách biệt, việc phối hợp chúng để sử dụng cùng một dll sẽ trở nên khó khăn hơn.


1

Tùy chọn thứ ba của bạn là phù hợp nhất (thêm nó dưới dạng một dự án "thư viện lớp" riêng biệt vào giải pháp). Điều này kết hợp những lợi ích của tất cả các phương pháp:

  • "Dự án trợ giúp" của bạn luôn được cập nhật trên tất cả các dự án khác nhau.
  • Bạn có thể tham khảo mã của dự án khi bạn muốn nhanh chóng thấy các thay đổi.
  • Bạn có thể xây dựng nó cho phiên bản .NET chính xác mỗi lần.
  • Dù sao thì bạn cũng có thể nhúng DLL vào exe, vì vậy đừng lo lắng về việc bạn có thể có nó như là một phần của bản dựng.

Chúng tôi làm điều này mọi lúc và tôi không thể làm gì ngoài việc đề xuất phương pháp này.

Một lựa chọn thứ tư khác mà bạn chưa đề cập là đưa nó vào kho lưu trữ NuGet riêng, cho phép bạn phiên bản chính xác và tham chiếu nó mà không cần dự án bổ sung trong mỗi giải pháp.


2
Hừm, với tôi, khi tôi thêm nó như một dự án vào giải pháp và sau đó tham chiếu dự án này trong các dự án khác, thì nó vẫn được tạo ra dưới dạng một tệp riêng biệt thay vì được nhúng ... Có điều gì tôi nên chỉ định không?
Bartosz

1

Là nhà phát triển, tôi luôn muốn đưa tham chiếu giải pháp của tiện ích vào ứng dụng của mình vì nó cho phép tôi gỡ lỗi mã (và phát hiện ra các lỗi có thể có trong Tiện ích!) Cộng với mọi thay đổi được thực hiện đối với tiện ích sẽ được tự động đưa vào ứng dụng.

Vì vậy, thực sự quyết định phụ thuộc vào mức độ trưởng thành của Tiện ích ! Nếu bạn không chắc chắn về các lỗi của Tiện ích, thì bạn phải luôn bao gồm tệp .cs của tiện ích đó để tìm ra các lỗi .. Nhưng nếu bạn chắc chắn rằng Tiện ích đã đủ chín muồi và nó sẽ không trả về kết quả với bất kỳ lỗi nào ở đó không có phạm vi để nâng cao trong Tiện ích, bạn có thể tiếp tục và bao gồm tệp DLL.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.