Praktik Terbaik: Penerapan Versi Kontrak Data

Topik ini mencantumkan praktik terbaik untuk membuat kontrak data yang dapat berkembang dengan mudah dari waktu ke waktu. Untuk informasi selengkapnya tentang kontrak data, lihat topiknya di Menggunakan Kontrak Data.

Catatan tentang Validasi Skema

Dalam membahas penerapan versi kontrak data, penting untuk dicatat bahwa skema kontrak data yang diekspor oleh Windows Communication Foundation (WCF) tidak memiliki dukungan penerapan versi apa pun, selain fakta bahwa elemen ditandai sebagai opsional secara default.

Ini berarti bahwa bahkan skenario penerapan versi yang paling umum, seperti menambahkan anggota data baru, tidak dapat diterapkan dengan cara yang mulus sehubungan dengan skema tertentu. Versi kontrak data yang lebih baru (dengan anggota data baru, misalnya) tidak memvalidasi menggunakan skema lama.

Namun, ada banyak skenario di mana kepatuhan skema yang ketat tidak diperlukan. Banyak platform layanan Web, termasuk layanan Web XML dan WCF yang dibuat menggunakan ASP.NET, tidak melakukan validasi skema secara default dan karena itu menoleransi elemen tambahan yang tidak dijelaskan oleh skema. Saat bekerja dengan platform semacam itu, banyak skenario pembuatan versi lebih mudah diterapkan.

Dengan demikian, ada dua kumpulan pedoman pembuatan versi kontrak data: satu kumpulan untuk skenario tempat validitas skema yang ketat penting, dan satu kumpulan lagi untuk skenario saat tidak demikian.

Penerapan versi saat validasi skema diperlukan

Jika validitas skema yang ketat diperlukan ke segala arah (baru-ke-lama dan lama-ke-baru), kontrak data harus dianggap tidak berubah. Jika penerapan versi diperlukan, kontrak data baru harus dibuat, dengan nama atau ruang nama yang berbeda, dan kontrak layanan menggunakan jenis data harus di-versi yang sesuai.

Misalnya, kontrak layanan pemrosesan pesanan pembelian bernama PoProcessing dengan operasi PostPurchaseOrder mengambil parameter yang sesuai dengan kontrak data PurchaseOrder. Jika kontrak PurchaseOrder harus berubah, Anda harus membuat kontrak data baru, yaitu, PurchaseOrder2, yang mencakup perubahan. Anda kemudian harus menangani penerapan versi di tingkat kontrak layanan. Misalnya, dengan membuat operasi PostPurchaseOrder2 yang mengambil parameter PurchaseOrder2, atau dengan membuat kontrak layanan PoProcessing2 tempat operasi PostPurchaseOrder mengambil kontrak data PurchaseOrder2.

Perhatikan bahwa perubahan dalam kontrak data yang dirujuk oleh kontrak data lain juga meluas ke lapisan model layanan. Misalnya, dalam skenario sebelumnya kontrak data PurchaseOrder tidak perlu berubah. Namun, ini berisi anggota data kontrak data Customer, yang pada gilirannya berisi anggota data dar kontrak data Address, yang memang perlu diubah. Dalam hal ini, Anda perlu membuat kontrak data Address2 dengan perubahan yang diperlukan, kontrak data Customer2 yang berisi anggota data Address2, dan kontrak data PurchaseOrder2 yang berisi anggota data Customer2. Seperti dalam kasus sebelumnya, kontrak layanan harus di-versi juga.

Meskipun dalam contoh ini nama diubah (dengan menambahkan "2"), rekomendasinya adalah mengubah kumpulan nama XML, bukan nama dengan menambahkan kumpulan nama XML baru dengan nomor versi atau tanggal. Misalnya, kontrak data http://schemas.contoso.com/2005/05/21/PurchaseOrder akan berubah menjadi kontrak data http://schemas.contoso.com/2005/10/14/PurchaseOrder.

Untuk informasi selengkapnya, lihat Praktik Terbaik: Penerapan Versi Layanan.

Terkadang, Anda harus menjamin kepatuhan skema yang ketat untuk pesan yang dikirim oleh aplikasi Anda, tetapi tidak dapat mengandalkan pesan masuk agar sesuai dengan skema. Dalam hal ini, ada bahaya bahwa pesan masuk mungkin berisi data asing. Nilai asing disimpan dan dikembalikan oleh WCF dan dengan demikian menghasilkan pesan skema-tidak valid yang dikirim. Untuk menghindari masalah ini, fitur round-tripping harus dinonaktifkan. Ada dua cara untuk melakukannya.

Untuk informasi lebih lanjut tentang bolak-balik, lihat Kontrak Data yang Kompatibel dengan Penerusan.

Penerapan Versi Saat Validasi Skema Tidak Diperlukan

Kepatuhan skema yang ketat jarang diperlukan. Banyak platform menoleransi elemen tambahan yang tidak dijelaskan oleh skema. Selama ini ditoleransi, serangkaian fitur lengkap yang dijelaskan dalam Penerapan Versi Kontrak Data dan Kontrak Data yang Kompatibel dengan Penerusan dapat digunakan. Panduan berikut direkomendasikan.

Beberapa pedoman harus diikuti secara persis untuk mengirim versi baru dari jenis yang lebih mengharapkan yang lama atau mengirim yang lama ke tempat yang baru diharapkan. Pedoman lain tidak benar-benar diperlukan, tetapi tercantum di sini karena mereka mungkin dipengaruhi oleh pembuatan versi skema selanjutnya.

  1. Jangan mencoba untuk membuat versi kontrak data berdasarkan jenis warisan. Untuk membuat versi yang lebih baru, ubah kontrak data pada jenis yang sudah ada atau buat jenis baru yang tidak terkait.

  2. Penggunaan warisan bersama dengan kontrak data diperbolehkan, asalkan warisan tidak digunakan sebagai mekanisme pembuatan versi dan bahwa aturan tertentu diikuti. Jika jenis berasal dari jenis dasar tertentu, jangan membuatnya berasal dari jenis dasar yang berbeda dalam versi mendatang (kecuali jika memiliki kontrak data yang sama). Ada satu pengecualian untuk ini: Anda dapat memasukkan jenis ke dalam hierarki antara jenis kontrak data dan jenis dasarnya, tetapi hanya jika tidak berisi anggota data dengan nama yang sama dengan anggota lain dalam versi yang mungkin berasal dari jenis lain dalam hierarki. Secara umum, menggunakan anggota data dengan nama yang sama pada tingkat yang berbeda dari hierarki warisan yang sama dapat menyebabkan masalah versi yang serius dan harus dihindari.

  3. Dimulai dengan versi pertama kontrak data, selalu terapkan IExtensibleDataObject untuk mengaktifkan round-tripping. Untuk informasi selengkapnya, lihat Kontrak Data yang Kompatibel Dengan Penerusan. Jika Anda telah merilis satu atau beberapa versi jenis tanpa menerapkan antarmuka ini, terapkan di versi jenis berikutnya.

  4. Di versi yang lebih baru, jangan mengubah nama kontrak data atau ruang nama. Jika mengubah nama atau kumpulan nama XML jenis yang mendasari kontrak data, pastikan untuk mempertahankan nama kontrak data dan kumpulan nama XML dengan menggunakan mekanisme yang sesuai, seperti properti Name dari DataContractAttribute. Untuk mengetahui informasi selengkapnya tentang pemberian nama, lihat Nama Kontrak Data.

  5. Di versi yang lebih baru, jangan mengubah nama anggota data mana pun. Jika mengubah nama bidang, properti, atau peristiwa yang mendasari anggota data, gunakan properti Name dari DataMemberAttribute untuk mempertahankan nama anggota data yang ada.

  6. Dalam versi yang lebih baru, jangan mengubah jenis bidang, properti, atau peristiwa apa pun yang mendasari anggota data, sehingga kontrak data yang dihasilkan untuk anggota data tersebut berubah. Perlu diingat bahwa jenis antarmuka setara dengan Object untuk tujuan menentukan kontrak data yang diharapkan.

  7. Di versi yang lebih baru, jangan ubah urutan anggota data yang ada dengan menyesuaikan properti Order dari DataMemberAttribute atribut.

  8. Dalam versi yang lebih baru, anggota data baru dapat ditambahkan. Mereka harus selalu mengikuti aturan-aturan ini:

    1. Properti IsRequired harus selalu dibiarkan pada nilai default false.

    2. Jika nilai default null atau nol untuk anggota tidak dapat diterima, metode panggilan balik harus disediakan menggunakan OnDeserializingAttribute untuk memberikan default yang wajar jika anggota tidak ada di aliran masuk. Untuk informasi selengkapnya tentang panggilan balik, lihat Panggilan Balik Serialisasi Toleran Versi.

    3. Properti DataMemberAttribute.Order harus digunakan untuk memastikan bahwa semua anggota data yang baru ditambahkan muncul setelah anggota data yang ada. Cara yang disarankan untuk melakukan ini adalah sebagai berikut: Tidak ada anggota data dalam versi pertama kontrak data yang harus memiliki kumpulan properti Order mereka. Semua anggota data yang ditambahkan dalam versi 2 kontrak data harus mengatur properti Order mereka ke 2. Semua anggota data yang ditambahkan dalam versi 3 dari kontrak data harus mengatur Order ke 3, dan seterusnya. Diperbolehkan memiliki lebih dari satu anggota data yang diatur ke nomor yang sama Order.

  9. Jangan hapus anggota data di versi yang lebih baru, meskipun properti IsRequired ditinggalkan di properti default false di versi sebelumnya.

  10. Jangan ubah properti IsRequired pada anggota data yang ada dari versi ke versi.

  11. Untuk anggota data yang diperlukan (di mana IsRequired adalah true), jangan ubah properti EmitDefaultValue dari versi ke versi.

  12. Jangan mencoba membuat hierarki versi bercabang. Artinya, harus selalu ada jalur setidaknya satu arah dari versi apa pun ke versi lain hanya menggunakan perubahan yang diizinkan oleh pedoman ini.

    Misalnya, jika versi 1 dari kontrak data Orang hanya berisi anggota data Nama, Anda tidak boleh membuat versi 2a dari kontrak yang hanya menambahkan anggota Usia dan versi 2b yang hanya menambahkan anggota Alamat. Pergi dari 2a ke 2b akan melibatkan menghapus Usia dan menambahkan Alamat; pergi ke arah lain akan memerlukan menghapus Alamat dan menambahkan Usia. Menghapus anggota tidak diizinkan oleh pedoman ini.

  13. Anda umumnya tidak boleh membuat sub-jenis baru dari jenis kontrak data yang ada dalam versi baru aplikasi Anda. Demikian juga, Anda tidak boleh membuat kontrak data baru yang digunakan sebagai pengganti anggota data yang dinyatakan sebagai Objek atau jenis antarmuka. Membuat kelas baru ini hanya diperbolehkan saat Anda tahu bahwa Anda dapat menambahkan jenis baru ke daftar jenis yang diketahui dari semua contoh aplikasi lama Anda. Misalnya, di versi 1 aplikasi Anda, Anda mungkin memiliki jenis kontrak data LibraryItem dengan sub-jenis kontrak data Buku dan Surat Kabar. LibraryItem kemudian akan memiliki daftar jenis yang diketahui yang berisi Buku dan Surat Kabar. Misalkan Anda sekarang menambahkan jenis Majalah di versi 2 yang merupakan sub-jenis LibraryItem. Jika Anda mengirim instans Majalah dari versi 2 ke versi 1, kontrak data Majalah tidak ditemukan dalam daftar jenis yang diketahui dan pengecualian dikeluarkan.

  14. Anda tidak boleh menambahkan atau menghapus anggota enumerasi di antara versi. Anda juga tidak boleh mengganti nama anggota enumerasi, kecuali Anda menggunakan properti Nama pada atribut EnumMemberAttribute untuk menjaga nama mereka dalam model kontrak data tetap sama.

  15. Koleksi dapat dipertukarkan dalam model kontrak data seperti yang dijelaskan dalam Jenis Koleksi dalam Kontrak Data. Hal ini memungkinkan untuk tingkat fleksibilitas yang besar. Namun, pastikan bahwa Anda tidak secara tidak sengaja mengubah jenis koleksi dengan cara yang tidak dapat dipertukarkan dari versi ke versi. Misalnya, jangan ubah dari koleksi yang tidak disesuaikan (yaitu, tanpa atribut CollectionDataContractAttribute) menjadi koleksi yang disesuaikan atau koleksi yang disesuaikan menjadi koleksi yang tidak disesuaikan. Selain itu, jangan ubah properti pada CollectionDataContractAttribute dari versi ke versi. Satu-satunya perubahan yang diizinkan adalah menambahkan properti Name atau Kumpulan nama XML jika nama atau kumpulan nama XML jenis koleksi yang mendasarinya telah berubah dan Anda perlu membuat nama kontrak data dan kumpulan nama XML sama seperti di versi sebelumnya.

Beberapa pedoman yang tercantum di sini dapat diabaikan dengan aman saat keadaan khusus berlaku. Pastikan Anda sepenuhnya memahami mekanisme serialisasi, deserialisasi, dan skema yang terlibat sebelum menyimpang dari pedoman.

Lihat juga