Pada bulan Februari 2019, 
ReactiveUI 9 , kerangka kerja lintas platform untuk membangun aplikasi GUI pada platform Microsoft .NET, dirilis. 
ReactiveUI adalah alat untuk mengintegrasikan ekstensi reaktif dengan pola desain MVVM. Kenalan dengan kerangka kerja dapat dimulai dengan 
serangkaian artikel tentang HabrΓ© atau 
dari halaman depan dokumentasi . Pembaruan ReactiveUI 9 mencakup banyak 
perbaikan dan peningkatan , tetapi mungkin perubahan yang paling menarik dan signifikan adalah 
integrasi yang erat dengan kerangka kerja DynamicData , yang memungkinkan bekerja dengan mengubah koleksi dengan gaya reaktif. Mari kita coba mencari tahu dalam kasus apa 
DynamicData dapat 
berguna dan bagaimana kerangka reaktif yang kuat ini diatur di dalam!
Latar belakang
Pertama, kita mendefinisikan berbagai tugas yang 
dipecahkan DynamicData dan mencari tahu mengapa alat standar untuk bekerja dengan mengubah set data dari 
System.Collections.ObjectModel namespace tidak cocok untuk kita.
Template MVVM, seperti yang Anda ketahui, melibatkan pembagian tanggung jawab antara lapisan model, presentasi, dan model presentasi aplikasi. Lapisan model diwakili oleh entitas domain dan layanan, dan tidak tahu apa-apa tentang model presentasi. Lapisan model merangkum seluruh logika aplikasi kompleks, dan model presentasi mendelegasikan operasi model, memberikan tampilan akses ke informasi tentang keadaan aplikasi saat ini melalui properti yang dapat diamati, perintah, dan koleksi. Alat standar untuk bekerja dengan mengubah properti adalah antarmuka 
INotifyPropertyChanged , 
INotifyPropertyChanged untuk bekerja dengan tindakan pengguna, dan 
INotifyCollectionChanged mengimplementasikan koleksi dan mengimplementasikan 
ObservableCollection dan 
ReadOnlyObservableCollection .

Implementasi 
INotifyPropertyChanged dan 
ICommand biasanya tetap pada hati nurani pengembang dan kerangka kerja MVVM yang digunakan, tetapi penggunaan 
ObservableCollection memberlakukan sejumlah batasan pada kami! Misalnya, kami tidak dapat mengubah koleksi dari utas latar belakang tanpa 
Dispatcher.Invoke Panggilan atau panggilan serupa, dan ini bisa berguna jika bekerja dengan array data yang beberapa operasi latar belakang disinkronkan dengan server. Perlu dicatat bahwa dalam MVVM idiomatik, lapisan model tidak perlu tahu tentang arsitektur aplikasi GUI yang digunakan, dan kompatibel dengan model dari MVC atau MVP, dan inilah sebabnya banyak 
Dispatcher.Invoke memungkinkan akses ke kontrol antarmuka pengguna dari latar belakang thread running dalam layanan domain, melanggar prinsip berbagi tanggung jawab antara lapisan aplikasi.
Tentu saja, dalam layanan domain akan dimungkinkan untuk mendeklarasikan suatu peristiwa, dan sebagai argumen dari suatu peristiwa, memberikan potongan dengan data yang diubah. Kemudian berlangganan acara tersebut, bungkus 
Dispatcher.Invoke Panggilan di antarmuka sehingga tidak tergantung pada kerangka GUI yang digunakan, pindah 
Dispatcher.Invoke model presentasi dan ubah 
ObservableCollection yang Dapat 
ObservableCollection kebutuhan, namun ada cara yang jauh lebih sederhana dan lebih elegan untuk menyelesaikan berbagai tugas yang ditunjukkan tanpa harus menulis sepeda . Ayo mulai belajar!
Ekstensi reaktif. Kelola aliran data
Untuk pemahaman lengkap tentang abstraksi yang diperkenalkan oleh 
DynamicData dan prinsip-prinsip bekerja dengan mengubah dataset reaktif, mari kita ingat 
apa itu pemrograman reaktif dan bagaimana menerapkannya dalam konteks platform Microsoft .NET dan pola desain MVVM . Cara untuk mengatur interaksi antar komponen program dapat bersifat interaktif dan reaktif. Dalam interaksi interaktif, fungsi konsumen secara sinkron menerima data dari fungsi penyedia (pendekatan berbasis-tarik, 
T , 
IEnumerable ), dan dalam interaksi reaktif, fungsi konsumen secara tidak sinkron mengirimkan data ke fungsi konsumen (pendekatan berbasis-push, 
Task , 
IObservable ).
 Pemrograman reaktif
Pemrograman reaktif adalah pemrograman menggunakan aliran data asinkron, dan ekstensi reaktif adalah kasus khusus dari implementasinya, berdasarkan pada 
IObserver dan 
IObserver dari namespace Sistem, yang mendefinisikan sejumlah operasi mirip LINQ pada antarmuka 
IObservable , yang disebut LINQ over Observable. Ekstensi reaktif mendukung .NET Standard dan berfungsi di mana pun platform Microsoft .NET berfungsi.

Kerangka kerja ReactiveUI mengundang pengembang aplikasi untuk mengambil keuntungan dari implementasi reaktif 
ICommand dan 
INotifyPropertyChanged , menyediakan alat yang kuat seperti 
ReactiveCommand<TIn, TOut> dan 
WhenAnyValue . 
WhenAnyValue memungkinkan 
WhenAnyValue untuk mengkonversi properti kelas yang mengimplementasikan INotifyPropertyChanged menjadi aliran peristiwa tipe 
IObservable<T> , yang menyederhanakan penerapan properti dependen.
 public class ExampleViewModel : ReactiveObject { [Reactive]  
ReactiveCommand<TIn, TOut> memungkinkan Anda untuk bekerja dengan perintah tersebut, seperti kejadian tipe 
IObservable<TOut> , yang diterbitkan kapan pun perintah menyelesaikan eksekusi. Juga, perintah apa pun memiliki properti 
IObservable<Exception> tipe 
IObservable<Exception> .
 
Selama ini kami bekerja dengan 
IObservable<T> , seperti peristiwa yang menerbitkan nilai baru tipe 
T setiap kali keadaan objek yang dipantau berubah. Sederhananya, 
IObservable<T> adalah aliran peristiwa, urutan membentang dari waktu ke waktu.
Tentu saja, kami dapat dengan mudah dan alami bekerja dengan koleksi - setiap kali koleksi berubah, publikasikan koleksi baru dengan elemen yang diubah. Dalam hal ini, nilai yang dipublikasikan akan bertipe 
IEnumerable<T> atau lebih terspesialisasi, dan event itu sendiri akan bertipe 
IObservable<IEnumerable<T>> . Tetapi, seperti yang ditunjukkan oleh pembaca yang berpikir kritis, ini penuh dengan masalah serius dengan kinerja aplikasi, terutama jika tidak ada selusin elemen dalam koleksi kami, tetapi seratus, atau bahkan beberapa ribu!
Pengantar DynamicData
DynamicData adalah perpustakaan yang memungkinkan Anda menggunakan kekuatan penuh ekstensi reaktif saat bekerja dengan koleksi. Ekstensi reaktif di luar kotak tidak menyediakan cara optimal untuk bekerja dengan mengubah kumpulan data, dan 
tugas DynamicData adalah memperbaikinya. Di sebagian besar aplikasi, ada kebutuhan untuk memperbarui koleksi secara dinamis - biasanya, koleksi diisi dengan beberapa elemen ketika aplikasi dimulai, dan kemudian diperbarui secara tidak sinkron, menyinkronkan informasi dengan server atau database. Aplikasi modern cukup kompleks, dan seringkali ada kebutuhan untuk membuat proyeksi koleksi - filter, ubah atau sortir elemen. DynamicData dirancang hanya untuk menghilangkan kode yang sangat rumit yang kita perlukan untuk mengelola set data yang berubah secara dinamis. Alat ini dikembangkan dan difinalisasi secara aktif, dan sekarang lebih dari 60 operator untuk bekerja dengan koleksi didukung.
 DynamicData
DynamicData bukan merupakan implementasi alternatif dari 
ObservableCollection<T> . Arsitektur 
DynamicData didasarkan terutama pada konsep-konsep pemrograman khusus domain. Ideologi penggunaan didasarkan pada fakta bahwa Anda mengelola beberapa sumber data, kumpulan yang dapat diakses oleh kode yang bertanggung jawab untuk menyinkronkan dan mengubah data. Selanjutnya, Anda menerapkan sejumlah operator ke sumber, yang dengannya Anda dapat mengubah data secara deklaratif, tanpa perlu secara manual membuat dan memodifikasi koleksi lainnya. Bahkan, dengan 
DynamicData Anda memisahkan operasi baca dan tulis, dan Anda hanya bisa membaca dengan cara reaktif - karena itu, koleksi yang diwarisi akan selalu disinkronkan dengan sumbernya.
Alih-alih 
IObservable<T> klasik, DynamicData mendefinisikan operasi pada 
IObservable<IChangeSet<T>>> dan 
IObservable<IChangeSet<TValue, TKey>> , di mana 
IChangeSet adalah bongkahan berisi informasi tentang perubahan koleksi - jenis perubahan dan elemen yang terpengaruh. Pendekatan ini dapat secara signifikan meningkatkan kinerja kode untuk bekerja dengan koleksi yang ditulis dengan gaya reaktif. Pada saat yang sama, 
IObservable<IChangeSet<T>> selalu dapat diubah menjadi 
IObservable<IEnumerable<T>> biasa 
IObservable<IEnumerable<T>> jika menjadi perlu untuk memproses semua elemen koleksi sekaligus. Jika kedengarannya rumit - jangan khawatir, dari contoh kode semuanya akan menjadi jelas dan transparan!
Contoh DynamicData
Mari kita lihat serangkaian contoh untuk lebih memahami bagaimana DynamicData bekerja, perbedaannya dengan 
System.Reactive dan tugas apa yang dapat diselesaikan oleh pengembang perangkat lunak aplikasi biasa dengan GUI. Mari kita mulai dengan contoh komprehensif yang 
diposting oleh DynamicData di GitHub . Dalam contoh, sumber data adalah 
SourceCache<Trade, long> , yang berisi kumpulan transaksi. Tugasnya adalah hanya menampilkan transaksi aktif, mengubah model menjadi objek proxy, mengurutkan koleksi.
 
Dalam contoh di atas, ketika Anda mengubah 
SourceCache , yang merupakan sumber data, 
ReadOnlyObservableCollection juga 
ReadOnlyObservableCollection berubah. Dalam hal ini, saat menghapus elemen dari koleksi, metode 
Dispose akan dipanggil, koleksi akan selalu diperbarui hanya dalam aliran GUI dan tetap diurutkan dan difilter. Keren, tidak ada 
Dispatcher.Invoke Kode 
Dispatcher.Invoke dan rumit!
SourceList dan Sumber Data SourceCache
DynamicData menyediakan dua koleksi khusus yang dapat digunakan sebagai sumber data yang bisa berubah. Koleksi ini adalah tipe 
SourceList dan 
SourceCache<TObject, TKey> . Disarankan untuk menggunakan 
SourceCache setiap kali 
TObject memiliki kunci unik, jika tidak gunakan 
SourceList . Objek-objek ini menyediakan .NET developer API untuk memodifikasi data - 
Add , 
Remove , 
Insert dan sejenisnya. Untuk mengonversi sumber data ke 
IObservable<IChangeSet<T>> atau 
IObservable<IChangeSet<T, TKey>> , gunakan operator 
.Connect() . Misalnya, jika Anda memiliki layanan yang memperbarui koleksi elemen di latar belakang, Anda dapat dengan mudah menyinkronkan daftar elemen-elemen ini dengan GUI, tanpa 
Dispatcher.Invoke dan ekses arsitektur:
 public class BackgroundService : IBackgroundService {  
DynamicData menggunakan tipe .NET bawaan untuk memetakan data ke dunia luar. Menggunakan operator DynamicData yang kuat, kita dapat mengubah 
IObservable<IChangeSet<Trade>> menjadi 
ReadOnlyObservableCollection model tampilan kami.
 public class TradesViewModel : ReactiveObject { private readonly ReadOnlyObservableCollection<TradeVm> _trades; public ReadOnlyObservableCollection<TradeVm> Trades => _trades; public TradesViewModel(IBackgroundService background) {  
Selain 
Transform , 
Filter dan 
Sort , DynamicData mencakup sejumlah operator lain, mendukung pengelompokan, operasi logis, perataan koleksi, menggunakan fungsi agregasi, tidak termasuk elemen identik, elemen penghitungan, dan bahkan virtualisasi pada level model representasi. Baca lebih lanjut tentang semua operator di 
proyek README di GitHub .

Koleksi berulir tunggal dan ubah pelacakan
Selain 
SourceList dan 
SourceCache , pustaka DynamicData juga menyertakan implementasi single-threaded dari koleksi yang bisa diubah - 
ObservableCollectionExtended . Untuk menyinkronkan dua koleksi di model tampilan Anda, deklarasikan satu sebagai 
ObservableCollectionExtended dan yang lainnya sebagai 
ReadOnlyObservableCollection dan gunakan operator 
ToObservableChangeSet , yang berperilaku sama seperti 
Connect tetapi dirancang untuk bekerja dengan 
ObservableCollection .
 
DynamicData juga mendukung pelacakan perubahan di kelas yang mengimplementasikan antarmuka 
INotifyPropertyChanged . Misalnya, jika Anda ingin diberitahu tentang perubahan koleksi setiap kali properti item berubah, gunakan 
AutoRefresh dan berikan pemilih properti yang diinginkan dengan argumen. 
AutoRefesh dan operator DynamicData lainnya akan memungkinkan Anda untuk dengan mudah dan alami memvalidasi sejumlah besar formulir dan sub-formulir yang ditampilkan di layar!
 
Berdasarkan fungsionalitas DynamicData, Anda dapat dengan cepat membuat antarmuka yang cukup kompleks - ini terutama berlaku untuk sistem yang menampilkan sejumlah besar data waktu nyata, sistem pengiriman pesan instan, dan sistem pemantauan.

Kesimpulan
Ekstensi reaktif adalah alat yang ampuh yang memungkinkan Anda bekerja secara deklaratif dengan data dan antarmuka pengguna, menulis kode portabel dan didukung, dan memecahkan masalah rumit dengan cara yang sederhana dan elegan. 
ReactiveUI memungkinkan pengembang .NET untuk secara erat mengintegrasikan ekstensi reaktif ke dalam proyek mereka menggunakan arsitektur MVVM dengan memberikan implementasi reaktif dari 
INotifyPropertyChanged dan 
ICommand , sementara 
DynamicData menangani sinkronisasi pengumpulan dengan menerapkan 
INotifyCollectionChanged , memperluas kemampuan ekstensi reaktif dan menjaga kinerja.
Pustaka ReactiveUI dan 
DynamicData kompatibel dengan kerangka kerja GUI paling populer dari platform .NET, termasuk Windows Presentation Foundation, Universal Windows Platform, 
Avalonia , Xamarin. Android, Formulir Xamarin, Xamarin.iOS. Anda dapat mulai mempelajari DynamicData dari 
halaman dokumentasi ReactiveUI yang sesuai . Pastikan juga untuk memeriksa proyek 
DynamicData Snippets , yang berisi contoh penggunaan DynamicData untuk semua kesempatan.