Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam tutorial ini Anda akan mempelajari apa arti pembuatan versi di .NET. Anda juga akan mempelajari faktor-faktor yang perlu dipertimbangkan saat membuat versi perpustakaan Anda serta memutakhirkan ke versi perpustakaan yang baru.
Versi bahasa
Pengkompilasi C# adalah bagian dari .NET SDK. Secara default, pengkompilasi memilih versi bahasa C# yang cocok dengan TFM yang dipilih untuk proyek Anda. Jika versi SDK lebih besar dari kerangka kerja yang Anda pilih, pengkompilasi dapat menggunakan versi bahasa yang lebih besar. Anda dapat mengubah default dengan mengatur LangVersion elemen dalam proyek Anda. Anda dapat mempelajari caranya di artikel kami tentang opsi kompilator.
Peringatan
Mengatur elemen LangVersion menjadi latest tidak disarankan. Pengaturan latest berarti pengompiler yang diinstal menggunakan versi terbarunya. Hal itu dapat berubah dari satu mesin ke mesin lainnya, membuat rakit tidak dapat diandalkan. Selain itu, ini memungkinkan fitur bahasa yang mungkin memerlukan fitur runtime atau fitur pustaka yang tidak termasuk dalam SDK saat ini.
Perpustakaan Penyusun
Sebagai pengembang yang telah membuat pustaka .NET untuk penggunaan umum, kemungkinan besar Anda pernah berada dalam situasi di mana Anda harus meluncurkan pembaruan baru. Bagaimana cara Anda menjalankan proses ini sangat penting karena Anda perlu memastikan bahwa ada transisi mulus dari kode yang ada ke pustaka Anda yang baru. Berikut ini adalah beberapa hal yang perlu dipertimbangkan saat membuat rilis baru:
Versi Semantik
Penerapan versi semantik (singkatnya SemVer) adalah konvensi penamaan yang diterapkan pada versi pustaka Anda untuk menandakan peristiwa milestone tertentu. Idealnya, informasi untuk versi yang Anda berikan kepada pustaka Anda akan membantu pengembang menentukan kompatibilitas dengan proyek mereka yang menggunakan versi lama dari pustaka yang sama.
Pendekatan yang paling mendasar untuk SemVer adalah format 3 komponen MAJOR.MINOR.PATCH, di mana:
-
MAJORdinaikkan saat Anda membuat perubahan API yang tidak kompatibel -
MINORbertambah ketika Anda menambahkan fungsionalitas dengan cara yang tetap kompatibel dengan versi sebelumnya -
PATCHditingkatkan ketika Anda melakukan perbaikan bug yang kompatibel ke belakang
Memahami kenaikan versi dengan contoh
Untuk membantu mengklarifikasi kapan harus menaikkan setiap nomor versi, berikut adalah contoh konkret:
Peningkatan versi UTAMA (perubahan API yang tidak kompatibel)
Perubahan ini mengharuskan pengguna untuk mengubah kode mereka agar berfungsi dengan versi baru:
Menghapus metode atau properti publik:
// Version 1.0.0 public class Calculator { public int Add(int a, int b) => a + b; public int Subtract(int a, int b) => a - b; // This method exists } // Version 2.0.0 - MAJOR increment required public class Calculator { public int Add(int a, int b) => a + b; // Subtract method removed - breaking change! }Mengubah tanda tangan metode:
// Version 1.0.0 public void SaveFile(string filename) { } // Version 2.0.0 - MAJOR increment required public void SaveFile(string filename, bool overwrite) { } // Added required parameterMengubah perilaku metode yang ada dengan cara yang merusak ekspektasi:
// Version 1.0.0 - returns null when file not found public string ReadFile(string path) => File.Exists(path) ? File.ReadAllText(path) : null; // Version 2.0.0 - MAJOR increment required public string ReadFile(string path) => File.ReadAllText(path); // Now throws exception when file not found
Versi MINOR (fungsionalitas yang kompatibel ke belakang)
Perubahan ini menambahkan fitur baru tanpa merusak kode yang ada:
Menambahkan metode atau properti publik baru:
// Version 1.0.0 public class Calculator { public int Add(int a, int b) => a + b; } // Version 1.1.0 - MINOR increment public class Calculator { public int Add(int a, int b) => a + b; public int Multiply(int a, int b) => a * b; // New method added }Menambahkan kelebihan beban baru:
// Version 1.0.0 public void Log(string message) { } // Version 1.1.0 - MINOR increment public void Log(string message) { } // Original method unchanged public void Log(string message, LogLevel level) { } // New overload addedMenambahkan parameter opsional ke metode yang ada:
// Version 1.0.0 public void SaveFile(string filename) { } // Version 1.1.0 - MINOR increment public void SaveFile(string filename, bool overwrite = false) { } // Optional parameterCatatan
Ini adalah perubahan yang kompatibel dengan sumber, tetapi perubahan pemecahan biner. Pengguna pustaka ini harus melakukan kompilasi ulang agar bisa bekerja dengan benar. Banyak pustaka akan mempertimbangkan ini hanya dalam perubahan versi utama , bukan perubahan versi minor .
"Peningkatan versi PATCH (perbaikan bug yang tetap kompatibel dengan versi sebelumnya)"
Perubahan ini memperbaiki masalah tanpa menambahkan fitur baru atau merusak fungsionalitas yang ada:
Memperbaiki bug dalam implementasi metode yang ada:
// Version 1.0.0 - has a bug public int Divide(int a, int b) { return a / b; // Bug: doesn't handle division by zero } // Version 1.0.1 - PATCH increment public int Divide(int a, int b) { if (b == 0) throw new ArgumentException("Cannot divide by zero"); return a / b; // Bug fixed, behavior improved but API unchanged }Peningkatan performa yang tidak mengubah API:
// Version 1.0.0 public List<int> SortNumbers(List<int> numbers) { return numbers.OrderBy(x => x).ToList(); // Slower implementation } // Version 1.0.1 - PATCH increment public List<int> SortNumbers(List<int> numbers) { var result = new List<int>(numbers); result.Sort(); // Faster implementation, same API return result; }
Prinsip utamanya adalah: jika kode yang ada dapat menggunakan versi baru Anda tanpa perubahan apa pun, ini adalah pembaruan MINOR atau PATCH. Jika kode yang ada perlu dimodifikasi untuk bekerja dengan versi baru Anda, ini adalah pembaruan MAJOR.
Ada juga cara untuk menentukan skenario lain, misalnya, versi pra-rilis, saat menerapkan informasi versi ke pustaka .NET Anda.
Kesesuaian Mundur
Saat Anda merilis versi baru perpustakaan Anda, kompatibilitas mundur dengan versi sebelumnya kemungkinan besar akan menjadi salah satu perhatian utama Anda. Versi baru pustaka Anda adalah sumber yang kompatibel dengan versi sebelumnya jika kode yang bergantung pada versi sebelumnya dapat, saat dikompilasi ulang, bekerja dengan versi baru. Versi baru pustaka Anda kompatibel dengan biner jika aplikasi yang bergantung pada versi lama dapat, tanpa kompilasi ulang, bekerja dengan versi baru.
Berikut adalah beberapa hal yang perlu dipertimbangkan saat mencoba mempertahankan kompatibilitas mundur dengan versi perpustakaan Anda yang lebih lama:
- Metode virtual: Ketika Anda mengubah metode virtual menjadi non-virtual di versi baru Anda, proyek yang melakukan override metode tersebut harus diperbarui. Ini merupakan perubahan besar yang mengubah dan sangat tidak dianjurkan.
- Signature metode: Saat memperbarui perilaku metode mengharuskan Anda untuk mengubah signaturenya juga, Anda sebaiknya membuat overload agar pemanggilan kode ke metode tersebut tetap berfungsi. Anda dapat memanipulasi tanda tangan metode lama untuk memanggil tanda tangan metode baru sehingga implementasi tetap konsisten.
- Atribut usang: Anda dapat menggunakan atribut ini dalam kode Anda untuk menentukan kelas atau anggota kelas yang tidak digunakan lagi dan kemungkinan akan dihapus di versi mendatang. Ini memastikan pengembang yang menggunakan pustaka Anda lebih siap menghadapi perubahan signifikan.
- Argumen Metode Opsional: Ketika Anda membuat argumen metode opsional sebelumnya menjadi wajib atau mengubah nilai defaultnya, maka semua kode yang tidak menyediakan argumen tersebut perlu diperbarui.
Catatan
Membuat argumen kompulsori opsional harus memiliki efek yang sangat sedikit terutama jika tidak mengubah perilaku metode.
Semakin mudah Anda membuatnya bagi pengguna untuk meningkatkan ke versi baru perpustakaan Anda, semakin besar kemungkinan mereka akan meningkatkan lebih cepat.
File Konfigurasi Aplikasi
Sebagai pengembang .NET, kemungkinan besar Anda menemukan file app.config yang ada di sebagian besar jenis proyek.
File konfigurasi sederhana ini dapat membantu meningkatkan peluncuran pembaruan baru. Secara umum Anda harus mendesain perpustakaan Anda sedemikian rupa sehingga informasi yang cenderung berubah secara teratur disimpan dalam file app.config, dengan cara ini ketika informasi tersebut diperbarui, file konfigurasi versi lama hanya perlu diganti dengan yang baru tanpa perlu untuk mengkompilasi ulang perpustakaan.
Menggunakan Pustaka
Sebagai pengembang yang menggunakan pustaka .NET yang dibuat oleh pengembang lain, kemungkinan besar Anda menyadari bahwa versi baru pustaka mungkin tidak sepenuhnya kompatibel dengan proyek Anda dan Anda mungkin sering harus memperbarui kode agar dapat bekerja dengan perubahan tersebut.
Beruntung bagi Anda, C# dan ekosistem .NET hadir dengan fitur dan teknik yang memungkinkan kita memperbarui aplikasi dengan mudah agar berfungsi dengan versi pustaka baru yang mungkin memperkenalkan perubahan yang memutus kompatibilitas.
Pengalihan Pengikatan Perakitan
Anda bisa menggunakan file app.config untuk memperbarui versi pustaka yang digunakan aplikasi Anda. Dengan menambahkan apa yang disebut pengalihan pengikatan, Anda dapat menggunakan versi pustaka baru tanpa harus mengulang kompilasi aplikasi Anda. Contoh berikut menunjukkan bagaimana Anda akan memperbarui file app.config aplikasi Anda untuk menggunakan patch 1.0.1 dari versi ReferencedLibrary alih-alih versi 1.0.0 yang awalnya digunakan untuk mengompilasi.
<dependentAssembly>
<assemblyIdentity name="ReferencedLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="en-us" />
<bindingRedirect oldVersion="1.0.0" newVersion="1.0.1" />
</dependentAssembly>
Catatan
Pendekatan ini hanya akan berfungsi jika versi baru dari ReferencedLibrary kompatibel secara biner dengan aplikasi Anda.
Lihatlah bagian Kompatibilitas Mundur di atas untuk mengetahui perubahan saat menentukan kompatibilitas.
baru
Anda menggunakan pengubah new untuk menyembunyikan anggota dari kelas dasar yang diwariskan. Ini adalah salah satu cara kelas turunan dapat merespons pembaruan di kelas-kelas dasar.
Ambil contoh berikut:
public class BaseClass
{
public void MyMethod()
{
Console.WriteLine("A base method");
}
}
public class DerivedClass : BaseClass
{
public new void MyMethod()
{
Console.WriteLine("A derived method");
}
}
public static void Main()
{
BaseClass b = new BaseClass();
DerivedClass d = new DerivedClass();
b.MyMethod();
d.MyMethod();
}
Hasil
A base method
A derived method
Dari contoh di atas Anda dapat melihat bagaimana DerivedClassmenyembunyikan metode MyMethod yang ada di BaseClass.
Ini berarti bahwa ketika kelas dasar di versi baru perpustakaan menambahkan anggota yang sudah ada di kelas turunan Anda, Anda cukup menggunakan pengubah new pada anggota kelas turunan untuk menyembunyikan anggota kelas dasar.
Ketika tidak ada pengubah new yang ditentukan, kelas turunan secara default akan menyembunyikan anggota yang bertentangan di kelas dasar, meskipun peringatan kompilator akan dihasilkan kode akan tetap dikompilasi. Ini berarti bahwa dengan hanya menambahkan anggota baru ke kelas yang ada, versi baru perpustakaan Anda tersebut akan kompatibel secara sumber dan biner dengan kode yang bergantung padanya.
ambil alih
Pengubah override mengartikani implementasi turunan memperluas implementasi anggota kelas dasar daripada menyembunyikannya. Anggota kelas dasar harus menerapkan pengubah virtual ke dalam.
public class MyBaseClass
{
public virtual string MethodOne()
{
return "Method One";
}
}
public class MyDerivedClass : MyBaseClass
{
public override string MethodOne()
{
return "Derived Method One";
}
}
public static void Main()
{
MyBaseClass b = new MyBaseClass();
MyDerivedClass d = new MyDerivedClass();
Console.WriteLine($"Base Method One: {b.MethodOne()}");
Console.WriteLine($"Derived Method One: {d.MethodOne()}");
}
Hasil
Base Method One: Method One
Derived Method One: Derived Method One
Pengubah override dievaluasi pada waktu kompilasi dan pengompilasi akan menghasilkan kesalahan jika tidak menemukan anggota virtual untuk mengganti.
Pengetahuan Anda tentang teknik yang dibahas dan pemahaman Anda tentang situasi di mana menggunakannya, akan sangat membantu dalam memudahkan transisi antar versi perpustakaan.