Solution dan Project

Organisasi multi-proyek dan referensi antar-proyek.

Daftar isi

Proyek yang tumbuh biasanya dipecah menjadi beberapa proyek yang saling bergantung, misalnya pustaka logika, pustaka pengujian, dan aplikasi utama. Solution adalah wadah yang mencatat seluruh proyek terkait beserta konfigurasinya, sehingga satu perintah build memproses semuanya dalam urutan yang benar. Topik ini membuat satu solution berisi dua proyek, menghubungkan keduanya dengan referensi proyek, dan membangunnya sekaligus dari terminal.

Solution sebagai wadah proyek#

Solution disimpan sebagai satu berkas teks yang berisi daftar proyek dan pengaturan build, tetapi tidak berisi kode apa pun, sehingga berkas itu tidak menggantikan proyek melainkan mengelompokkannya. Sejak .NET 10, format solution baru yang dihasilkan dotnet new sln adalah slnx, yaitu solution berbentuk XML yang lebih mudah dibaca dan ditinjau, sedangkan format klasik .sln tetap didukung penuh. Berkas solution biasanya ikut tersimpan pada repositori bersama kode sumbernya, sehingga seluruh pengembang dan sistem otomatis memakai daftar proyek yang sama persis. Perubahan keanggotaan proyek pun tercatat sebagai perubahan berkas, dan peninjauan kode dapat melihat penambahan atau penghapusan proyek tersebut sebagaimana perubahan kode biasa. Contoh berikut membuat solution bernama organisasi.slnx di folder latihan sementara.

bash
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# siapkan folder latihan yang bersih di /tmp, lalu buat solution baru
rm -rf /tmp/cs-eko/organisasi
dotnet new sln -o /tmp/cs-eko/organisasi | grep "created successfully"
text Keluaran
The template "Solution File" was created successfully.

Menambahkan proyek ke solution#

Solution yang baru dibuat masih kosong, sehingga dua proyek contoh dibuat terlebih dahulu, yaitu pustaka bernama Penghitung dan aplikasi console bernama Aplikasi. Opsi --no-restore menunda pemulihan karena pemasangan dependensi belum diperlukan pada tahap pengorganisasian ini. Template class library menghasilkan berkas Class1.cs sebagai kelas awal yang namanya tinggal diganti, sedangkan template console menghasilkan Program.cs dengan satu baris cetakan, dan keduanya cukup untuk memeriksa keterkaitan build sebelum kode sesungguhnya ditulis.

bash
# buat pustaka dan aplikasi console di dalam folder latihan, tanpa pemulihan agar cepat
dotnet new classlib -o /tmp/cs-eko/organisasi/Penghitung --no-restore | grep "created successfully"
dotnet new console -o /tmp/cs-eko/organisasi/Aplikasi --no-restore | grep "created successfully"
text Keluaran
The template "Class Library" was created successfully.
The template "Console App" was created successfully.

Pendaftaran proyek ke solution dilakukan dengan dotnet sln add, yang menerima lebih dari satu proyek sekaligus. Jalur proyek pada keluarannya dicetak relatif terhadap folder solution, sehingga teksnya sama persis meskipun perintahnya menuliskan jalur absolut.

bash
# daftarkan kedua proyek ke dalam solution
dotnet sln /tmp/cs-eko/organisasi/organisasi.slnx add /tmp/cs-eko/organisasi/Penghitung/Penghitung.csproj /tmp/cs-eko/organisasi/Aplikasi/Aplikasi.csproj
text Keluaran
Project `Penghitung/Penghitung.csproj` added to the solution.
Project `Aplikasi/Aplikasi.csproj` added to the solution.

Daftar proyek yang tercatat diperiksa dengan dotnet sln list, dan keluarannya menampilkan jalur relatif tiap proyek secara alfabetis. Pengeluaran proyek dari solution memakai dotnet sln remove dengan bentuk argumen yang sama dengan add, sehingga keanggotaan solution dapat disesuaikan kapan pun tanpa menyunting berkasnya secara manual.

bash
# periksa daftar proyek yang tercatat pada solution
dotnet sln /tmp/cs-eko/organisasi/organisasi.slnx list
text Keluaran
Project(s)
----------
Aplikasi/Aplikasi.csproj
Penghitung/Penghitung.csproj

Referensi antar-proyek#

Proyek yang bergantung pada proyek lain mencatatnya sebagai ProjectReference, berbeda dengan PackageReference yang menunjuk package NuGet. Referensi proyek dipakai ketika kedua proyek dikembangkan bersama dalam satu repositori, karena perubahan pada pustaka langsung terlihat oleh aplikasi tanpa penerbitan package apa pun. Kaitannya dibuat dengan dotnet add reference.

bash
# buat Aplikasi bergantung pada Penghitung melalui referensi proyek
dotnet add /tmp/cs-eko/organisasi/Aplikasi/Aplikasi.csproj reference /tmp/cs-eko/organisasi/Penghitung/Penghitung.csproj
text Keluaran
Reference `..\Penghitung\Penghitung.csproj` added to the project.

Catatan pemisah jalur pada keluaran tersebut menggunakan gaya Windows meskipun perintahnya dijalankan di Linux, karena format pesan SDK ditulis sama di semua sistem operasi. Hasilnya tercatat pada berkas proyek pemakai sebagai elemen berikut.

xml Contoh: ProjectReference pada Aplikasi.csproj
<ItemGroup>
  <ProjectReference Include="..\Penghitung\Penghitung.csproj" />
</ItemGroup>

Setelah referensi dibuat, kelas public pada proyek Penghitung dapat dipanggil langsung dari kode Aplikasi tanpa langkah tambahan. Grafik ketergantungan ini juga menentukan urutan build, yaitu pustaka selalu dibangun lebih dahulu sebelum aplikasi yang meminjamnya, dan referensi yang membentuk lingkaran ditolak oleh SDK karena urutan bangunnya tidak mungkin ditentukan.

Membangun dan menjalankan solution#

Perintah dotnet build pada berkas solution membangun seluruh proyek yang tercatat di dalamnya mengikuti grafik ketergantungan, sehingga ringkasan hasilnya mewakili semua proyek sekaligus. Konfigurasi build yang diminta diterapkan ke semua proyek, misalnya dotnet build -c Release mengompilasi seluruh proyek dalam konfigurasi Release dengan satu perintah, sedangkan folder keluaran tiap proyek tetap terpisah di dalam bin masing-masing.

bash
# bangun seluruh proyek pada solution sekaligus
dotnet build /tmp/cs-eko/organisasi/organisasi.slnx 2>&1 | grep -E "succeeded|Warning|Error"
text Keluaran
Build succeeded.
    0 Warning(s)
    0 Error(s)

Pembangunan juga dapat ditujukan ke satu proyek saja, dan SDK tetap membangun pustaka yang direferensikannya lebih dahulu. Perhatikan urutan baris keluaran berikut, yaitu Penghitung selesai sebelum Aplikasi.

bash
# bangun satu proyek saja, pustaka yang direferensikannya ikut terbangun lebih dahulu
dotnet build /tmp/cs-eko/organisasi/Aplikasi/Aplikasi.csproj 2>&1 | grep -E "\->|succeeded"
text Keluaran
  Penghitung -> /tmp/cs-eko/organisasi/Penghitung/bin/Debug/net10.0/Penghitung.dll
  Aplikasi -> /tmp/cs-eko/organisasi/Aplikasi/bin/Debug/net10.0/Aplikasi.dll
Build succeeded.

Aplikasi di dalam solution dijalankan dengan dotnet run --project yang menunjuk folder proyeknya, dan pustaka yang direferensikan ikut terbangun secara otomatis bila belum ada. Pola inilah yang dipakai proyek profesional, yaitu aplikasi utama tetap ramping karena logika yang dapat dipakai ulang dipindahkan ke proyek pustaka, sedangkan setiap pustaka itu dapat diuji secara terpisah melalui proyek pengujian yang mereferensikannya dengan cara yang sama.

Kesalahan umum#

  • Membangun proyek satu per satu dari foldernya masing-masing. Perintah build yang terpisah tidak menjamin urutan dan konfigurasi yang sama, sehingga solution dipakai sebagai titik bangun tunggal untuk seluruh proyek.
  • Melupakan pendaftaran proyek pada solution. Proyek yang ada di folder tetapi tidak didaftarkan tetap bisa dibangun sendirian, tetapi dotnet build atas solution melewatkannya, sehingga perubahan pada proyek itu tidak terlihat pada build gabungan.
  • Membuat referensi melingkar antar-proyek. SDK menolak kaitan yang membentuk lingkaran karena urutan buildnya tidak terdefinisi, dan perbaikannya adalah memindahkan tipe yang dipakai bersama ke proyek ketiga yang dirujuk keduanya.

Ringkasan#

  • Solution adalah berkas daftar proyek dalam format slnx sejak .NET 10 atau .sln klasik, dibuat dengan dotnet new sln dan dimodifikasi dengan dotnet sln add, list, dan remove.
  • Ketergantungan antar-proyek dicatat sebagai ProjectReference melalui dotnet add reference, berbeda dari PackageReference yang menunjuk package NuGet.
  • Build atas solution memproses seluruh proyek mengikuti grafik ketergantungan, dan referensi melingkar ditolak SDK.

Referensi#