giriş
MVVM'de olağan uygulama, Görünümlerin ViewModel'lerini bir bağımlılık enjeksiyon (DI) konteynerinden çözerek bulmalarını sağlamaktır . Bu, kapsayıcıdan View sınıfının bir örneğini sağlaması (çözümlemesi) istendiğinde otomatik olarak gerçekleşir. Kap , ViewModel parametresini kabul eden View yapıcısını çağırarak ViewModel'i View'e enjekte eder ; bu şemaya kontrolün tersine çevrilmesi (IoC) denir .
DI'nin Faydaları
Buradaki ana fayda, kapsayıcının kendisinden istediğimiz türlerin nasıl çözüleceğine ilişkin talimatlarla çalışma zamanında yapılandırılabilmesidir . Bu, uygulamamız gerçekten çalıştığında kullandığımız türleri (Görünümler ve ViewModels) çözme talimatı vererek, ancak uygulama için birim testlerini çalıştırırken farklı şekilde talimat vererek daha fazla test edilebilirlik sağlar. İkinci durumda, uygulamanın bir UI'si bile olmayacaktır (çalışmıyor; sadece testler), bu nedenle kapsayıcı , uygulama çalışırken kullanılan "normal" türlerin yerine taklitleri çözecektir .
DI'dan kaynaklanan sorunlar
Şimdiye kadar, DI yaklaşımının, uygulama bileşenlerinin oluşturulması üzerine bir soyutlama katmanı ekleyerek uygulama için kolay test edilebilirlik sağladığını gördük. Bu yaklaşımla ilgili bir sorun var: Microsoft Expression Blend gibi görsel tasarımcılarla iyi oynamıyor .
Sorun, hem normal uygulama çalıştırmalarında hem de birim test çalıştırmalarında, birisinin kapsayıcıyı hangi türlerin çözüleceğine ilişkin talimatlarla kurması gerektiğidir; ek olarak, ViewModellerin bunlara enjekte edilebilmesi için birisinin konteynerden Görünümleri çözmesini istemesi gerekir.
Bununla birlikte, tasarım zamanında çalışan bir kodumuz yoktur . Tasarımcı, Görünümlerimizin örneklerini oluşturmak için yansımayı kullanmaya çalışır, bu şu anlama gelir:
- View yapıcısı bir ViewModel örneği gerektiriyorsa, tasarımcı Görünümü hiç başlatamaz - kontrollü bir şekilde hata verir.
- Görünüm parametresiz yapıcı varsa gör örneği, ancak onun
DataContext
olacak null
biz 'tasarımcı bir 'boş' bir görünüm elde edeceğiz böylece - çok kullanışlı değildir
ViewModelLocator'a girin
ViewModelLocator, şu şekilde kullanılan ek bir soyutlamadır:
- View, kaynaklarının bir parçası olarak bir ViewModelLocator oluşturur ve DataContext'i konumlandırıcının ViewModel özelliğine veri bağlar.
- Konum belirleyici , tasarım modunda olup olmadığımızı bir şekilde algılar.
- Tasarım modunda değilse, yer belirleyici yukarıda açıklandığı gibi DI konteynerinden çözdüğü bir ViewModel döndürür.
- Tasarım modundaysa, konumlandırıcı kendi mantığını kullanarak sabit bir "kukla" ViewModel döndürür (unutmayın: tasarım zamanında kap yoktur!); bu ViewModel tipik olarak kukla verilerle önceden doldurulmuş olarak gelir
Elbette bu, Görünüm'ün başlamak için parametresiz bir kurucuya sahip olması gerektiği anlamına gelir (aksi takdirde tasarımcı onu başlatamaz).
özet
ViewModelLocator, DI'nin avantajlarını MVVM uygulamanızda tutmanıza ve aynı zamanda kodunuzun görsel tasarımcılarla iyi oynamasına izin veren bir deyimdir. Bu bazen uygulamanızın "karıştırılabilirliği" olarak adlandırılır (İfade Karışımına atıfta bulunarak).
Yukarıdakileri sindirdikten sonra, burada pratik bir örneğe bakın .
Son olarak, veri şablonlarını kullanmak, ViewModelLocator'ı kullanmaya bir alternatif değil, kullanıcı arayüzünüzün bölümleri için açık View / ViewModel çiftlerini kullanmaya bir alternatiftir. Bunun yerine bir veri şablonu kullanabileceğiniz için, genellikle bir ViewModel için bir Görünüm tanımlamanıza gerek olmadığını fark edebilirsiniz.