Gevşek Bir Şekilde Eşlenen Bileşenler Arasında İletişim
Not
Bu e-Kitap 2017 baharında yayımlanmıştır ve o zamandan beri güncelleştirilmemiştir. Kitapta değerli kalan çok şey var, ancak bazı malzemeler güncelliğini yitirmiş.
Yayımlama-abone olma düzeni, yayımcıların abone olarak bilinen alıcıları bilmeden ileti gönderdiği bir mesajlaşma düzenidir. Benzer şekilde, aboneler herhangi bir yayımcı hakkında bilgi sahibi olmadan belirli iletileri dinler.
.NET'teki olaylar yayımlama-abone olma desenini uygular ve denetim ve onu içeren sayfa gibi gevşek bağlama gerekli değilse bileşenler arasındaki iletişim katmanı için en basit ve en basit yaklaşımdır. Ancak, yayımcı ve abone yaşam süreleri birbirine nesne başvuruları ile birleştirilmiştir ve abone türünün yayımcı türüne bir başvurusu olmalıdır. Bu, özellikle statik veya uzun ömürlü bir nesnenin olayına abone olan kısa ömürlü nesneler olduğunda bellek yönetimi sorunları oluşturabilir. Olay işleyicisi kaldırılmazsa, abone yayımcıdaki başvuru tarafından canlı tutulur ve bu, abonenin çöp toplamasını engeller veya geciktirecektir.
MessagingCenter'e giriş
Xamarin.FormsMessagingCenter
sınıfı yayımla-abone ol desenini uygulayarak nesneye ve tür başvurularına göre bağlantı kurması zor olan bileşenler arasında ileti tabanlı iletişime olanak sağlar. Bu mekanizma, yayımcıların ve abonelerin birbirlerine başvuruda bulunmadan iletişim kurmasına olanak tanır ve bileşenler arasındaki bağımlılıkları azaltmaya yardımcı olurken, bileşenlerin bağımsız olarak geliştirilip test edilmesine de olanak tanır.
sınıfı çok MessagingCenter
noktaya yayın yayımlama-abone olma işlevselliği sağlar. Bu, tek bir iletiyi yayımlayan birden çok yayımcı olabileceği ve aynı iletiyi dinleyen birden çok abone olabileceği anlamına gelir. Şekil 4-1'de bu ilişki gösterilmektedir:
Şekil 4-1: Çok noktaya yayın yayımlama-abone olma işlevi
Yayımcılar yöntemini kullanarak MessagingCenter.Send
ileti gönderirken, aboneler yöntemini kullanarak MessagingCenter.Subscribe
iletileri dinler. Ayrıca, aboneler gerekirse yöntemiyle ileti aboneliklerinin aboneliğini MessagingCenter.Unsubscribe
kaldırabilir.
Dahili olarak, MessagingCenter
sınıfı zayıf başvurular kullanır. Bu, nesneleri canlı tutmayacağı ve atık toplamalarına izin verileceği anlamına gelir. Bu nedenle, yalnızca bir sınıf artık iletiyi almak istemediğinde ileti aboneliğini kaldırmak gerekir.
eShopOnContainers mobil uygulaması, gevşek bir şekilde bağlanmış bileşenler arasında iletişim kurmak için sınıfını kullanır MessagingCenter
. Uygulama üç ileti tanımlar:
- İleti
AddProduct
, alışveriş sepetineCatalogViewModel
bir öğe eklendiğinde sınıf tarafından yayımlanır. Buna karşılık sınıf iletiyeBasketViewModel
abone olup yanıt olarak alışveriş sepetindeki öğelerin sayısını artırır. Ayrıca sınıfıBasketViewModel
da bu iletinin aboneliğini kaldırır. - İleti
Filter
, kullanıcı katalogdanCatalogViewModel
görüntülenen ürünlere marka veya tür filtresi uyguladığında sınıf tarafından yayımlanır. Buna karşılık,CatalogView
sınıfı iletiye abone olur ve kullanıcı arabirimini yalnızca filtre ölçütleriyle eşleşen öğelerin görüntülenmesi için güncelleştirir. - İleti,
ChangeTab
yeni bir siparişinMainViewModel
başarıyla oluşturulması ve gönderilmesi için aşağıdakineMainViewModel
gittiği zamanCheckoutViewModel
sınıfı tarafından yayımlanır. Buna karşılık sınıf iletiyeMainView
abone olur ve kullanıcı arabirimini kullanıcı siparişlerini gösterecek şekilde Profilim sekmesinin etkin olması için güncelleştirir.
Not
MessagingCenter
sınıfı gevşek bir şekilde bağlanmış sınıflar arasında iletişime izin verirken, bu soruna tek mimari çözümü sunmaz. Örneğin, bir görünüm modeli ile görünüm arasındaki iletişim, bağlama altyapısı ve özellik değişikliği bildirimleri aracılığıyla da gerçekleştirilebilir. Ayrıca, gezinti sırasında veri geçirilerek iki görünüm modeli arasındaki iletişim de sağlanabilir.
eShopOnContainers mobil uygulamasında, MessagingCenter
başka bir sınıfta gerçekleşen bir eyleme yanıt olarak kullanıcı arabiriminde güncelleştirmek için kullanılır. Bu nedenle, iletiler kullanıcı arabirimi iş parçacığında yayımlanır ve aboneler iletiyi aynı iş parçacığında alır.
İpucu
UI güncelleştirmeleri gerçekleştirirken kullanıcı arabirimi iş parçacığına hazırlama. Kullanıcı arabirimini güncelleştirmek için arka plan iş parçacığından gönderilen bir ileti gerekiyorsa, yöntemini çağırarak iletiyi abonedeki kullanıcı arabirimi iş parçacığında işleyin Device.BeginInvokeOnMainThread
.
hakkında MessagingCenter
daha fazla bilgi için bkz . MessagingCenter.
İleti Tanımlama
MessagingCenter
iletileri, iletileri tanımlamak için kullanılan dizelerdir. Aşağıdaki kod örneği, eShopOnContainers mobil uygulamasında tanımlanan iletileri gösterir:
public class MessageKeys
{
// Add product to basket
public const string AddProduct = "AddProduct";
// Filter
public const string Filter = "Filter";
// Change selected Tab programmatically
public const string ChangeTab = "ChangeTab";
}
Bu örnekte, iletiler sabitler kullanılarak tanımlanır. Bu yaklaşımın avantajı, derleme zamanı türü güvenliği ve yeniden düzenleme desteği sağlamasıdır.
İleti Yayımlama
Yayımcılar, aşırı yüklemelerden biriyle MessagingCenter.Send
bir iletiyi abonelere bildirir. Aşağıdaki kod örneği, iletiyi yayımlamayı AddProduct
gösterir:
MessagingCenter.Send(this, MessageKeys.AddProduct, catalogItem);
Bu örnekte yöntemi Send
üç bağımsız değişken belirtir:
- İlk bağımsız değişken gönderen sınıfını belirtir. Gönderen sınıfı, iletiyi almak isteyen tüm aboneler tarafından belirtilmelidir.
- İkinci bağımsız değişken iletiyi belirtir.
- Üçüncü bağımsız değişken aboneye gönderilecek yük verilerini belirtir. Bu durumda yük verileri bir
CatalogItem
örnektir.
Send
yöntemi, fire-and-forget yaklaşımını kullanarak iletiyi ve yük verilerini yayımlar. Bu nedenle, iletiyi almak için kayıtlı aboneler olmasa bile ileti gönderilir. Bu durumda, gönderilen ileti yoksayılır.
Not
yöntemi, iletilerin MessagingCenter.Send
teslim şeklini denetlemek için genel parametreleri kullanabilir. Bu nedenle, bir ileti kimliğini paylaşan ancak farklı yük veri türleri gönderen birden çok ileti farklı aboneler tarafından alınabiliyor.
İletiye Abone Olmak
Aboneler, aşırı yüklemelerden birini MessagingCenter.Subscribe
kullanarak bir ileti almak için kaydolabilir. Aşağıdaki kod örneği, eShopOnContainers mobil uygulamasının iletiyi nasıl abone olduğunu ve işlediğini AddProduct
gösterir:
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(
this, MessageKeys.AddProduct, async (sender, arg) =>
{
BadgeCount++;
await AddCatalogItemAsync(arg);
});
Bu örnekte yöntemi iletiye Subscribe
AddProduct
abonedir ve iletiyi almaya yanıt olarak bir geri çağırma temsilcisi yürütür. Lambda ifadesi olarak belirtilen bu geri çağırma temsilcisi, kullanıcı arabirimini güncelleştiren kodu yürütür.
İpucu
Sabit yük verilerini kullanmayı göz önünde bulundurun. Alınan verilere aynı anda birkaç iş parçacığı erişebileceği için, geri arama temsilcisinden yük verilerini değiştirmeyin. Bu senaryoda eşzamanlılık hatalarını önlemek için yük verilerinin sabit olması gerekir.
Abonenin yayımlanan iletinin her örneğini işlemesi gerekmeyebilir ve bu, yönteminde Subscribe
belirtilen genel tür bağımsız değişkenleri tarafından denetlenebilir. Bu örnekte abone yalnızca yük verileri bir CatalogItem
örnek olan sınıfından CatalogViewModel
gönderilen iletileri alırAddProduct
.
İletiden Abonelikten Çık
Aboneler artık almak istemedikleri iletilerin aboneliğini kaldırabilir. Bu, aşağıdaki kod örneğinde MessagingCenter.Unsubscribe
gösterildiği gibi aşırı yüklemelerden biriyle elde edilir:
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(this, MessageKeys.AddProduct);
Bu örnekte yöntem söz dizimi, Unsubscribe
iletiyi almak AddProduct
üzere abone olunduğunda belirtilen tür bağımsız değişkenlerini yansıtır.
Özet
Xamarin.FormsMessagingCenter
sınıfı yayımla-abone ol desenini uygulayarak nesneye ve tür başvurularına göre bağlantı kurması zor olan bileşenler arasında ileti tabanlı iletişime olanak sağlar. Bu mekanizma, yayımcıların ve abonelerin birbirlerine başvuruda bulunmadan iletişim kurmasına olanak tanır ve bileşenler arasındaki bağımlılıkları azaltmaya yardımcı olurken, bileşenlerin bağımsız olarak geliştirilip test edilmesine de olanak tanır.