2010-12-09 25 views
5

Basit bir uygulama oluşturmak için WPF ve Entity Framework ile MVVM tasarım desenini kullanmaya çalışıyordum. Eğer sınıflar gevşek bir şekilde birleştiyse her şey iyi ve iyi gider, ama eğer sth varsa. İki model sınıfı gibi: Müşteri ve Adres ve bir Müşteri adresleri var.MVVM, koleksiyonlar ve ORM

Artık bu sınıflar için iki VM sınıfı oluşturmam gerekiyor - CustomerVM ve AddressVM. CustomerVM, AddressVM nesnelerinin ObservableCollection olmalıdır. Bu VM sınıflarına yapılan her değişiklik (hem MüşteriVM hem de AddressVM'deki tüm CRUD işlemlerini içerir) model sınıflarına yansıtılmalı - bu yüzden, örneğin, bir kod dizisi yazmam gerekiyor. ObservableCollection değiştirilen olaya abone olur ve yeni bir nesne eklenirse, modele yeni bir nesne ekleyin ... ve benzeri ...

Bununla ne yapmalı? MVVM kullanırken bu normal mi? Ben her şeyi iyi yapıyorum? Böyle basit bir sınıf hiyerarşisi için gereken kod miktarını nasıl azaltabilirim? Hiyerarşideki diğer sınıflarla "iyi davranan" temel VM sınıfları yaratabilecek herhangi bir çerçeve var mı? Sınıf ilişkileri daha karmaşıksa ne yapmalı?

VEYA Basit koymak için: aynı Orada

Customer1.Adresses.Add(new Address{City="New York"}) 

: Model koleksiyonlarında vm koleksiyonlarında yapılan değişiklikleri yansıtacak şekilde nasıl

:

CustomerVM1.AdressesVM.Add(new AddressVM{City="New York"}) 

bir eşdeğerini neden olmalıdır Diğer taraftan problem - modelde koleksiyon modeline yapılan değişikliklerin nasıl yansıtılacağı, modele dahil olmak üzere, ancak birincisi ile daha çok ilgileniyorum çünkü daha pratik Uygulama ve vm nesneleri çoğu durumda basitçe yeniden yaratılabilir.

cevap

0

Modelimde düz bir eski koleksiyon ile ViewModel eşzamanlı olarak nasıl bir ObservableCollection tutmaya çalıştığınızı anlamaya çalıştığınızda tam olarak aynı soruna rastlıyorsunuz. Bir ObservableCollection harika çünkü Görünüm ona bağlanabiliyor ve koleksiyon değiştiğinde otomatik olarak değişebiliyor. Maalesef senkronizasyon sorununu bir seviye aşağı taşıdınız.

Modellerden birinde bile bir seçenek GözlemlenebilirKoleksiyonları kullanmaktır. Bu çok temiz bir mimari değil çünkü MVVM modele herhangi bir talepte bulunmuyor. Benim mimari şöyle yüzden, bir Presenter'ı tanıtmak olduğunu çözmeye yaptığı şey

:

View -> ViewModel <-> Presenter <-> Model 

Ayrıca, benim ViewModels dilsizyaptı.

  1. Kullanıcı tıkladığında Ekle düğmesi
  2. ViewModel ya Sunucu abone olduğu bir olayı yükseltir, veya sunum üzerinde bir yöntemi çağırır, ya da sadece bir çağıran: Tipik bir kullanıcı işlemi, başlangıcından sonuna kadar gerçekleşir İşte nasıl ViewModel oluşturulduğunda Presenter'ın ViewModel'e sağladığı geri çağrı. Esasen eylemi Presenter'a devretmektedir.
  3. Presenter, Modele Ekle'yi çağırır.
  4. Model, eski düz koleksiyon da dahil olmak üzere ilgili tüm durumlarını güncelleyerek Çağrıya yanıt verir.
  5. Modelde eylemi gerçekleştiren sunucu, daha sonra Model'den yeni durumu okur ve durumu, durumu ViewModel'a yazar. Bağlama, Görünümü senkronize etmeyi sağlar.

Yani sizin durumda, Sunucu ViewModel ObservableCollection bir CollectionChanged olaya abone olabilir ve onu değiştirir, bu model üzerinde ekle arayarak olaya tepki verir. Öte yandan, Presenter, Modele Ekle komutunu arayan başka bir kullanıcı eylemini işlediğinde (Model ile tüm etkileşimini kullandığını bilir), bu değişikliğin ObservableCollection'a yayılması gerektiğini bilir. ViewModel. Benim kod

, ben her kullanıcı eylemi Presenter ile Modeline yürütülür sonra durumu ... basitleştirilmiş, ben ViewModel uygulanabilir yere Modeli tüm ilgili devlet, düz bir kopyasını yapmak. İhtiyaç duyduğunuzdan biraz daha fazla iş yapıyorsunuz, ancak tipik bir CRUD türünde uygulamada dikkate değer bir performans sorunu yok. Eğer gerçekten büyük bir nesne koleksiyonum varsa, performans bir sorun olabilir ve daha karmaşık mantık pahasına, daha ince taneli bir senkronizasyona (sadece değişen varlığın güncellenmesi) düşüyorum.

+0

Harika bir cevap için çok teşekkür ederim. Bu, sorunu çözmenin bir yoludur, ancak IMO, daha az kod yazmanıza neden olmaz - bunu yapmanın daha temiz bir yoludur. Yine de başka bir katman olan Presenter'a ihtiyacınız var ve bunlar olması gerekenden daha karmaşık hale geliyor. – kubal5003

+0

Dün VM sınıfları oluşturmak yerine "azaltılmış" mvvm gibi bir şey yapmayı düşünüyordum - model sınıfını kısmi sınıfların kullanımı yoluyla genişletmek istiyorum. Şimdi ihtiyacım olan her özellik için, eski olanı - yani MVVM'de olduğu gibi - kapsülleyen bir tane daha yaratabilirim. Sade ve eski bir koleksiyon için sadece INotifyCollectionChanged'i uygulayan ve depolamak için düz eski koleksiyonu kullanan bir sarmalayıcı koleksiyonu oluşturabilirim. Bu konu hakkında ne düşünüyorsun? – kubal5003

+0

Düşünürken düşündüğüm bir şey belki de MyCollection gibi genel bir koleksiyon oluşturabilir -> bu model, model <-> viewmodel etkileşimleri hakkında ihtiyaç duyulan her şeyi bilmeli ve sunucuda yaptığınız her şeyi halledebilmelidir. İyi yazılmışsa, her yerde yeniden kullanılabilir. – kubal5003

1

Sen WPF Application Framework (WAF) ait BookLibrary örnek uygulamada ilginizi çekebilir. Entity Framework ve MVVM'nin birlikte nasıl kullanılacağını gösterir.

Kısa ipucu: Her varlık sınıfı için bir sarıcı ViewModel oluşturmuyor. Bunun yerine, Görünümler için ViewModel sınıfları oluşturur.