Berkomunikasi antara komponen yang digabungkan secara longgar

Tip

Konten ini adalah kutipan dari eBook, Pola Aplikasi Perusahaan Menggunakan .NET MAUI, tersedia di .NET Docs atau sebagai PDF gratis yang dapat diunduh yang dapat dibaca secara offline.

Enterprise Application Patterns Using .NET MAUI eBook cover thumbnail.

Pola terbitkan-berlangganan adalah pola olahpesan di mana penerbit mengirim pesan tanpa mengetahui penerima apa pun, yang dikenal sebagai pelanggan. Demikian pula, pelanggan mendengarkan pesan tertentu, tanpa mengetahui penerbit apa pun.

Peristiwa di .NET menerapkan pola terbitkan-berlangganan dan merupakan pendekatan paling sederhana untuk lapisan komunikasi antar komponen jika konek api longgar tidak diperlukan, seperti kontrol dan halaman yang berisinya. Namun, masa pakai penerbit dan pelanggan digabungkan oleh referensi objek satu sama lain, dan jenis pelanggan harus memiliki referensi ke jenis penerbit. Ini dapat membuat masalah manajemen memori, terutama ketika ada objek berumur pendek yang berlangganan peristiwa objek statis atau berumur panjang. Jika penanganan aktivitas tidak dihapus, pelanggan akan tetap hidup dengan referensi di penerbit, dan ini akan mencegah atau menunda pengumpulan sampah pelanggan.

Pengantar MVVM Toolkit Messenger

Antarmuka Toolkit IMessenger MVVM menjelaskan pola terbitkan-berlangganan, memungkinkan komunikasi berbasis pesan antar komponen yang tidak nyaman untuk ditautkan berdasarkan referensi objek dan jenis. Mekanisme ini memungkinkan penerbit dan pelanggan untuk berkomunikasi tanpa memiliki referensi langsung satu sama lain, membantu mengurangi dependensi antar komponen, sekaligus memungkinkan komponen dikembangkan dan diuji secara independen.

Catatan

MVVM Toolkit Messenger adalah bagian CommunityToolkit.Mvvm dari paket. Untuk informasi tentang cara menambahkan paket ke proyek Anda, lihat Pengantar Toolkit MVVM di Pusat Pengembang Microsoft.

Peringatan

.NET MAUI berisi kelas bawaan MessagingCenter yang tidak lagi direkomendasikan untuk digunakan dan harus ditransisikan ke MVVM Toolkit Messenger.

Antarmuka IMessenger memungkinkan fungsionalitas multicast publish-subscribe. Ini berarti bahwa mungkin ada beberapa penerbit yang menerbitkan satu pesan, dan mungkin ada beberapa pelanggan yang mendengarkan pesan yang sama. Gambar di bawah ini menggambarkan hubungan ini:

Multicast publish-subscribe functionality.

Ada dua implementasi IMessenger antarmuka yang disertakan CommunityToolkit.Mvvm dengan paket. Menggunakan WeakReferenceMessenger referensi lemah yang dapat mengakibatkan pembersihan yang lebih mudah untuk pelanggan pesan. Ini adalah opsi yang baik jika pelanggan Anda tidak memiliki siklus hidup yang ditentukan dengan jelas. menggunakan StrongReferenceMessenger referensi kuat yang dapat menghasilkan performa yang lebih baik dan masa pakai langganan yang lebih terkontrol dengan lebih jelas. Jika Anda memiliki alur kerja dengan masa pakai yang sangat terkontrol (misalnya, langganan yang terikat ke halaman OnAppearing dan OnDisappearing metode), StrongReferenceManager mungkin merupakan opsi yang lebih baik, jika performa menjadi perhatian. Kedua implementasi ini tersedia dengan implementasi default yang siap digunakan dengan merujuk baik WeakReferenceMessenger.Default atau StrongReferenceMessenger.Default.

Catatan

IMessenger Meskipun antarmuka mengizinkan komunikasi antara kelas yang dipasangkan secara longgar, antarmuka tidak menawarkan satu-satunya solusi arsitektur untuk masalah ini. Misalnya, komunikasi antara model tampilan dan tampilan juga dapat dicapai oleh mesin pengikatan dan melalui pemberitahuan perubahan properti. Selain itu, komunikasi antara dua model tampilan juga dapat dicapai dengan meneruskan data selama navigasi.

Aplikasi multi-platform eShopOnContainers menggunakan WeakReferenceMessenger kelas untuk berkomunikasi antara komponen yang digabungkan secara longgar. Aplikasi mendefinisikan satu pesan bernama AddProductMessage. AddProductMessage diterbitkan oleh CatalogViewModel kelas ketika item ditambahkan ke keramaian belanja. Sebagai gantinya CatalogView , kelas berlangganan pesan dan menggunakan ini untuk menyoroti penambahan produk dengan animasi sebagai respons.

Di aplikasi multi-platform eShopOnContainers, WeakReferenceMessenger digunakan untuk memperbarui UI sebagai respons terhadap tindakan yang terjadi di kelas lain. Oleh karena itu, pesan diterbitkan dari utas yang dijalankan kelas, dengan pelanggan menerima pesan pada utas yang sama.

Tip

Marsekal ke UI atau utas utama saat melakukan pembaruan UI. Jika pembaruan pada antarmuka pengguna tidak dibuat pada utas ini, itu dapat menyebabkan aplikasi crash atau menjadi tidak stabil.

Jika pesan yang dikirim dari utas latar belakang diperlukan untuk memperbarui UI, proses pesan pada utas UI di pelanggan dengan memanggil MainThread.BeginInvokeOnMainThread metode .

Untuk informasi selengkapnya tentang Messenger, lihat Messenger di Pusat Pengembang Microsoft.

Menentukan pesan

IMessenger pesan adalah objek kustom yang menyediakan payload kustom. Contoh kode berikut menunjukkan pesan yang AddProductMessage ditentukan dalam aplikasi multi-platform eShopOnContainers:

public class AddProductMessage : ValueChangedMessage<int>
{
    public AddProductMessage(int count) : base(count)
    {
    }
}

Kelas dasar didefinisikan menggunakan ValueChangedMessage<T> di mana T bisa dari jenis apa pun yang diperlukan untuk meneruskan data. Penerbit pesan dan pelanggan dapat mengharapkan pesan dengan jenis tertentu (misalnya, AddProductMessage). Hal ini dapat membantu memastikan bahwa kedua belah pihak telah menyetujui kontrak olahpesan dan bahwa data yang diberikan dengan kontrak tersebut akan konsisten. Selain itu, pendekatan ini menyediakan keamanan jenis waktu kompilasi dan dukungan pemfaktoran ulang.

Menerbitkan pesan

Untuk menerbitkan pesan, kita harus menggunakan metode .IMessenger.Send Ini dapat diakses paling umum melalui WeakReferenceMessenger.Default.Send atau StrongReferenceMessenger.Default.Send. Pesan yang dikirim bisa dari jenis objek apa pun. Contoh kode berikut menunjukkan penerbitan AddProduct pesan:

WeakReferenceMessenger.Default.Send(new Messages.AddProductMessage(BadgeCount));

Dalam contoh ini, Send metode menentukan menyediakan instans AddProductMessage baru objek untuk diterima pelanggan hilir. Parameter token kedua tambahan dapat ditambahkan untuk digunakan ketika beberapa pelanggan yang berbeda perlu menerima pesan dengan jenis yang sama tanpa menerima pesan yang salah.

Metode ini Send akan menerbitkan pesan, dan data payload-nya, menggunakan pendekatan fire-and-forget. Oleh karena itu, pesan dikirim bahkan jika tidak ada pelanggan yang terdaftar untuk menerima pesan. Dalam situasi ini, pesan terkirim diabaikan.

Berlangganan pesan

Pelanggan dapat mendaftar untuk menerima pesan menggunakan salah IMessenger.Register<T> satu kelebihan beban. Contoh kode berikut menunjukkan bagaimana aplikasi multi-platform eShopOnContainers berlangganan, dan memproses, AddProductMessage pesan:

WeakReferenceMessenger.Default
    .Register<CatalogView, Messages.AddProductMessage>(
        this,
        async (recipient, message) =>
        {
            await recipient.Dispatcher.DispatchAsync(
                async () =>
                {
                    await recipient.badge.ScaleTo(1.2);
                    await recipient.badge.ScaleTo(1.0);
                });
        });

Dalam contoh sebelumnya, Register metode berlangganan AddProductMessage pesan dan menjalankan delegasi panggilan balik sebagai respons untuk menerima pesan. Delegasi panggilan balik ini, yang ditentukan sebagai ekspresi lambda, menjalankan kode yang memperbarui UI.

Catatan

Hindari penggunaan this dalam delegasi panggilan balik Anda untuk menghindari pengambilan objek tersebut dalam delegasi. Ini dapat membantu meningkatkan performa. Sebagai gantinya, gunakan parameter recipient.

Jika data payload disediakan, jangan mencoba memodifikasi data payload dari dalam delegasi panggilan balik karena beberapa utas dapat mengakses data yang diterima secara bersamaan. Dalam skenario ini, data payload harus tidak dapat diubah untuk menghindari kesalahan konkurensi.

Berhenti berlangganan dari pesan

Pelanggan dapat berhenti berlangganan dari pesan yang tidak ingin mereka terima lagi. Ini dicapai dengan salah IMessenger.Unregister satu kelebihan beban, seperti yang ditunjukkan dalam contoh kode berikut:

WeakReferenceMessenger.Default.Unregister<Messages.AddProductMessage>(this);

Catatan

Dalam contoh ini, tidak sepenuhnya perlu dipanggil Unregister karena WeakReferenceMessenger akan memungkinkan objek yang tidak digunakan untuk dikumpulkan sampah. StrongReferenceMessenger Jika digunakan, disarankan untuk memanggil Unregister langganan apa pun yang tidak lagi digunakan.

Dalam contoh ini, Unsubscribe sintaks metode menentukan argumen jenis pesan dan objek penerima yang mendengarkan pesan.

Ringkasan

Antarmuka Toolkit IMessenger MVVM menjelaskan pola terbitkan-berlangganan, memungkinkan komunikasi berbasis pesan antar komponen yang tidak nyaman untuk ditautkan berdasarkan referensi objek dan jenis. Mekanisme ini memungkinkan penerbit dan pelanggan untuk berkomunikasi tanpa memiliki referensi satu sama lain, membantu mengurangi dependensi antar komponen, sekaligus memungkinkan komponen dikembangkan dan diuji secara independen.