Keuntungan menggunakan file .dll daripada menautkan file .cs ke proyek (untuk kelas pembantu / metode ekstensi umum saya sendiri)

38

Saya memiliki proyek pembantu yang saya gunakan di semua aplikasi yang saya buat. Ini berisi beberapa metode ekstensi dan banyak kelas pembantu umum, kontrol dll. Saya memperbarui / memperpanjang proyek pembantu dari waktu ke waktu. Ini biasanya proyek-proyek kecil dan tidak terkait, dan saya adalah satu-satunya orang yang mengerjakan semuanya.

Saya mencoba dua pendekatan untuk menggunakannya

  • tambahkan file .cs secara langsung (Tambahkan sebagai tautan) ke setiap proyek tempat saya menggunakannya
  • kompilasi sebagai .dll dan tambahkan sebagai referensi

Saya melihat beberapa manfaat dan kelemahan dari pendekatan ini.
Yang pertama:

  • lebih sederhana, karena kelas pembantu dikompilasi ke dalam file exe, oleh karena itu saya sering dapat dengan mudah menyediakan hanya satu file .exe yang akan berfungsi dengan baik. Karena saya menambahkan sebagai tautan, saya bisa sangat yakin bahwa setiap kali saya membangun proyek yang menggunakan helper, file helper akan menjadi versi terbaru.
  • bahkan lebih sederhana, karena saya dapat memisahkan file, sehingga metode ekstensi saya yang berjalan dengan baik di. NET 4.0 dapat direferensikan secara terpisah dari yang membutuhkan. NET 4.5, yang berarti bahwa aplikasi secara keseluruhan dapat berjalan di. NET 4.0
  • Memungkinkan untuk debug melalui kode, dengan semua manfaat breakpoints dll dll ...
  • sepertinya bukan 'praktik terbaik'

Yang kedua:

  • tampaknya merupakan pendekatan yang tepat, tetapi:
  • mengharuskan saya untuk mengirimkan file .dll terpisah, yang karena alasan tertentu jauh lebih sulit bagi pengguna (mereka cenderung berbagi program saya tanpa .dll, yang kemudian macet saat startup)
  • karena akan dikompilasi menjadi .dll tunggal, itu akan membutuhkan versi tertinggi dari .NET - banyak pengguna saya tidak memiliki .NET 4.5 dan hanya beberapa elemen dari kelas pembantu saya memerlukan ini, yang berarti saya dapat memaksa beberapa orang untuk memperbarui sistem mereka tanpa alasan
  • Saya juga perlu memastikan bahwa setiap kali saya memperbarui salah satu program saya, saya juga mengirimkan file .dll - meskipun saya tidak tahu apakah itu telah diubah sejak versi terakhir, atau tidak (bisa saja, tetapi bisa juga versi yang sama). Saya tidak bisa melihat cara sederhana untuk menentukan itu, tanpa melacak versi perakitan, yang merupakan pekerjaan tambahan. Untuk saat ini, ketika saya memperbarui program saya, saya hanya memberikan exe yang diperbarui, dan saya ingin tetap kecil dan rendah hati.

Jadi, apa manfaat sebenarnya dari penggunaan file .dll di sini? Harap dicatat, bahwa saya adalah satu-satunya orang yang mengedit kode semua aplikasi dan file pembantu.


Juga, untuk memperjelas - aplikasi biasanya sangat sedikit, sedangkan kode yang terkandung dalam kelas helper sepenuhnya generik untuk mereka semua (beberapa perbandingan string sederhana, jalur atau operasi XML dll)


Sebenarnya, seseorang membuat saya sadar sekarang bahwa ada pilihan ketiga. Karena saya memiliki kode pembantu dalam proyek separte, saya dapat menambahkan proyek ini ke solusi masing-masing aplikasi saya yang terpisah - yang berfungsi seperti 'Tambahkan sebagai tautan' untuk file tunggal, kecuali saya hanya menambahkan satu proyek ... Tapi seperti yang diperhatikan oleh Doc Brown, ini pada dasarnya berarti bahwa .dll perlu ditambahkan ke proyek ...

Namun hal lain yang agak mendukung tidak menggunakan file dll adalah kemampuan untuk debug melalui kelas pembantu secara aktif ...

Bartosz
sumber
3
Anda benar, dan saya bahkan melakukannya, karena ini membantu jika persyaratan .NET lebih tinggi ... Tapi saya tidak suka melakukannya ... Penginstal untuk aplikasi 40kb sedikit berlebihan :)
Bartosz
3
Ya, Anda selalu dapat menggunakan sesuatu seperti Costura , ini adalah alat untuk menggabungkan DLL. Anda dapat menggabungkan semua dependensi ke EXE, menyimpan satu file dan memungkinkan Anda untuk menggunakan pustaka yang diperlukan. Ini dapat diotomatiskan ke proses build, untuk mempermudah.
Kroltan
2
Ketika Anda menambahkan proyek ke solusi, Anda masih harus menggunakan DLL proyek ini, dengan semua kelemahan yang Anda sebutkan di atas.
Doc Brown
2
@DocBrown - sial, kau benar :)
Bartosz
1
Menautkan file atau proyek .cs dapat memiliki kelemahan lain. Jika Anda menggunakan file-file yang dibagikan ini di banyak proyek, dan satu proyek memerlukan perubahan besar pada pustaka bersama Anda, Anda sekarang perlu memperbaiki proyek-proyek Anda yang lain. Referensi dll akan melindungi Anda dari itu jika tidak ada alasan untuk kode Anda memerlukan logika yang diperbarui. Saya telah menjadi bagian dari tim pengembangan yang mengalami masalah ini ketika proyek bersama melibatkan hal-hal seperti otentikasi khusus. Pelanggan ingin mencoba perubahan untuk aplikasi baru, dan sekarang Anda perlu mengubah versi perpustakaan umum Anda. Menggunakan dll lakukan itu.
Ellesedil

Jawaban:

13

Anda telah melihat sebagian besar pro dan kontra. Menggunakan file cs sebagai referensi memang lebih ringan dan seringkali lebih mudah dikelola. Namun, saya sarankan untuk menggunakan pendekatan ini secara eksklusif ketika csfile Anda sepenuhnya lengkap dan tidak memiliki persyaratan membangun khusus.

Menggunakan DLL terpisah

  • akan membuat dependensi ke utilitas atau perpustakaan lain secara eksplisit (jadi selama Anda tidak memiliki dependensi seperti itu, itu akan berfungsi dengan baik)

  • akan memungkinkan Anda untuk mendefinisikan konfigurasi build spesifik (misalnya, jika sebuah kelas hanya bekerja di konfigurasi x86, atau membutuhkan setidaknya .NET 4.0, konfigurasi build dari assembly membuat persyaratan ini eksplisit).

Jadi terutama jika Anda memiliki banyak komponen kelas tunggal, mandiri, menggunakan referensi ke file baik-baik saja, tetapi jika Anda memiliki komponen yang merujuk komponen lain, atau persyaratan bangunan tertentu, saya akan merekomendasikan untuk menggunakan DLL.

Untuk mengurangi masalah dengan mengelola banyak DLL terpisah, Anda dapat membuat paket installer, atau menggunakan ILMerge , yang dapat menyematkan satu set rakitan ke dalam satu executable. Di lingkungan kami, kami menangani masalah secara berbeda, dengan menggunakan skrip penyebaran untuk setiap aplikasi. Script ini memastikan semua DLL yang diperlukan selalu dikirimkan ke produksi ketika rilis aplikasi baru diterbitkan.

Doc Brown
sumber
Ok, terima kasih banyak - jadi, apakah saya mengerti dengan benar, bahwa selama kelas pembantu saya tidak mereferensikan dll eksternal lain (hanya berisi kode .NET standar) bukan merupakan kekejian untuk hanya menautkannya?
Bartosz
@ Bartosz: tidak ada DLL eksternal, dan setiap kelas helper idealnya tidak menggunakan kelas helper lainnya, atau hanya kelas helper lainnya yang disimpan dalam file yang sama. Sejujurnya, pada tingkat tertentu Anda dapat mengelola situasi di mana kelas pembantu A membutuhkan kelas pembantu B yang disimpan dalam file terpisah, tetapi pendekatan ini tidak skalanya dengan baik.
Doc Brown
1
@PeterK. - ya, dan saya lakukan :)
Bartosz
1
@whatsisname: bukan ini tidak bisa bekerja. Namun, bagi saya itu tidak terdengar seperti solusi yang akan menyederhanakan hal-hal, lebih seperti yang dapat menyebabkan masalah yang tidak terduga ;-)
Doc Brown
1
@ Ozkan: di lingkungan kami, ini hanya penyebaran xcopy ke beberapa jaringan berbagi (dengan beberapa langkah tambahan untuk membuat cadangan versi sebelumnya dan memastikan tidak ada yang menggunakan program saat ini - yang dicapai dengan upaya mengubah nama folder penempatan terlebih dahulu). Ia tahu dll yang akan digunakan karena kami meng-hardcode daftar DLL yang diperlukan ke dalam skrip - tidak ada keajaiban di baliknya. Solusi ini tidak sempurna, tetapi bekerja untuk kami dalam banyak kasus, kecuali untuk program yang banyak digunakan oleh puluhan pengguna.
Doc Brown
11

DLL berguna saat aplikasi besar dan ada bagian yang memerlukan pembaruan, tetapi tidak seluruh aplikasi. Jadi, jika Anda menulis MS Word, akan berguna untuk memiliki kode periksa ejaan dalam DLL yang dapat diperbarui tanpa harus memperbarui keseluruhan MS Word. Jika yang Anda tulis adalah aplikasi utilitas kecil (atau serangkaian aplikasi mandiri yang terjadi pada semua orang menggunakan kode yang sama) itu tidak membuat banyak perbedaan apakah kode tersebut tertanam dalam aplikasi atau tidak.

dcguest
sumber
2

Anda telah menyimpulkannya dalam pertanyaan Anda, saya hanya punya beberapa poin untuk ditambahkan.

Opsi Mono adalah contoh yang bagus dari paket NuGet yang menggunakan pendekatan pertama dengan sangat baik.

Atau, jika Anda memutuskan untuk menggunakan dll, Anda dapat menggunakan alat-alat seperti Costura untuk menanamkan referensi itu di executable Anda sebagai sumber daya tertanam. Untuk menggunakannya cukup tambahkan Costura.Fodypaket:

Install-Package Costura.Fody
Justin
sumber
Sebenarnya, ada satu hal lagi - dengan proyek yang disematkan atau file yang ditambahkan sebagai tautan, Anda juga dapat secara aktif men-debug kode hingga masuk melalui file pembantu ...
Bartosz
1
@ Bartosz Saya pikir Anda masih bisa men-debug "semua jalan melalui" tanpa "file pembantu", selama Anda memiliki file pdb yang benar.
Zack
Saya mencoba Costura dan saya sangat menyukainya!
Bartosz
2

Apakah dll lebih bermanfaat atau tidak tergantung pada beberapa faktor:

  1. Ukuran kode (saat dikompilasi).
  2. Berapa banyak ongkos yang menggunakannya.
  3. Seberapa sering Anda berniat memperbarui kode.
  4. Apakah ongkos tersebut dimaksudkan untuk disimpan bersama atau ada sepenuhnya secara terpisah.

Tujuan dari pustaka bersama adalah untuk mengambil kode yang umum untuk banyak file yang dapat dieksekusi dan memusatkannya sehingga semua file yang dapat dieksekusi berbagi salinan. Ini dimaksudkan untuk menghemat ruang dan membuat kode lebih mudah diperbarui.

Jika jumlah kode di kelas helper Anda sangat kecil, mungkin tidak ada gunanya memindahkannya ke dll karena overhead kode berada di dll dapat menangkal manfaat penghematan ruang karena memusatkannya.

Selain itu, jika Anda hanya membuat beberapa executable, ukuran kode di setiap executable mungkin cukup kecil untuk tidak menjadi masalah. Namun, semakin banyak executable yang Anda gunakan dengan kode yang sama, semakin menguntungkan jika kode tersebut dipindahkan ke dll.

Sebagai contoh yang disederhanakan, misalkan kelas pembantu Anda mengkompilasi ke 128 byte dalam file exe, tetapi ketika dipindahkan ke dll, dll adalah 512 byte. Jika Anda hanya memiliki 3 executable, Anda akan menghemat ruang dengan memasukkan kode di executable. Namun jika Anda memiliki 5 executable, Anda akan berada pada titik di mana Anda akan lebih baik memiliki dll karena ruang gabungan diambil oleh 5 salinan kode (5 * 128 = 640 byte) lebih dari ruang yang diambil dengan memiliki kode dalam dll (512 byte).

Sekarang katakan misalnya Anda menemukan bug dalam kode pembantu Anda. Jika Anda mengkompilasi semua file executable Anda dengan kode yang dimasukkan, Anda harus mengkompilasi ulang setiap file yang dapat dieksekusi dan kemudian mendistribusikan kembali versi yang dikompilasi. Jika Anda mengkompilasi kode ke dll, Anda hanya perlu mengkompilasi ulang dan mendistribusikan satu dll, dan bug secara otomatis akan diperbaiki untuk semua executable yang menggunakannya.

Terakhir, untuk sebuah program untuk menemukan dll itu harus tahu di mana harus mencari dll. Jika Anda menyimpan semua executable Anda, Anda bisa meletakkan dll di direktori yang sama dan mereka semua akan langsung menemukannya. Jika Anda sengaja memisahkan mereka, menjadi lebih sulit untuk mengoordinasikan mereka untuk menggunakan dll yang sama.

Pharap
sumber
1

Pilihan ketiga Anda adalah yang paling tepat (tambahkan itu sebagai proyek "perpustakaan kelas" yang terpisah untuk solusi). Ini menggabungkan manfaat dari semua pendekatan:

  • "Proyek pembantu" Anda selalu terkini di semua proyek yang berbeda.
  • Anda dapat referensi kode proyek ketika Anda ingin melihat perubahan dengan cepat.
  • Anda dapat membangunnya untuk versi .NET yang benar setiap kali.
  • Anda dapat menanamkan DLL di exe, jadi jangan khawatir bahwa Anda hanya bisa memilikinya sebagai bagian dari bangunan Anda.

Kami melakukan ini sepanjang waktu dan saya tidak bisa melakukan apa pun selain merekomendasikan pendekatan ini.

Alternatif keempat lain yang belum Anda sebutkan adalah meletakkannya di repositori NuGet pribadi yang akan membuat Anda versi dengan benar dan referensi tanpa proyek tambahan di setiap solusi.

Benjamin Gruenbaum
sumber
2
Hm, tampak bagi saya bahwa ketika saya menambahkannya sebagai proyek ke solusi dan kemudian referensi proyek ini di proyek lain, maka itu masih dibuat sebagai .dll terpisah daripada tertanam ... Apakah ada sesuatu yang harus saya tentukan?
Bartosz
1

Sebagai seorang pengembang, saya selalu ingin menyertakan referensi solusi utilitas untuk aplikasi saya karena memungkinkan saya men-debug kode (dan menemukan kemungkinan bug di Utilitas juga!) Ditambah setiap perubahan yang dibuat pada utilitas secara otomatis termasuk dalam aplikasi.

Jadi, sebenarnya keputusan tergantung pada seberapa matang Utilitas itu! Jika Anda tidak yakin tentang bug Utilitas, maka Anda harus selalu menyertakan file .cs utilitas itu untuk mengetahui bug .. Tetapi jika Anda yakin Utilitas itu cukup matang dan tidak akan mengembalikan hasil dengan bug apa pun dan ada tidak ada ruang untuk peningkatan dalam Utilitas, Anda dapat melanjutkan dan memasukkan file DLL.

saruchi arora
sumber