2010-12-08 16 views
5

Uygulamamda, MemberListView ve MemberEditView öğelerinde iki kez göründüğümü varsayalım. Onlar perspektif görünümüModels, MemberListViewModel ve MemberEditViewModel ile ilişkilidir. Modeller, üye sınıfı için CRUD yöntemlerine sahip olan bir repository sınıfı olan MemberRepository ile konuşuyor.MVVM ve Deposu Soru

MemberEditView formunda, Durum (Etkin/Aktif Değil/Beklemede), üye ticaret kodu vb. Gibi fikirleri gösteren birkaç açılır menü vardır. Bunlar, viewModel'imdeki ObservableCollection nesneleridir ve görünümde ComboBox'lara bağlıdır. MemberRepository, görüntülenecek her birinin listesini almak için gerekenleri ele almalı mı?

ÜyeEditView'de, üyenin yıllar içinde sahip olduğu tüm işleri görüntüleyen bir ızgaram var. Kullanıcı işlerden birini ikiye katlıyorsa, İş Bilgilerini görüntülemek için bir JobHistoryEditView çağrısı yapar ve JobHistoryViewModel içerir. MemberRepository JobHistory CRUD yöntemlerine dikkat etmeli mi yoksa ayrı bir JobHistory Deposu mu olmalıdır?

cevap

2

En MVVM uygulamalar bu mimariyi olurdu: Geçenlerde bir varyantını savunan edilmiştir

View -> ViewModel -> Model -> Repository 

:

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

(A -> B "A noktasından B bilir" anlamına gelir ama B A.) hakkında bilgi sahibi değildir.

Her iki durumda da, depo hakkında bildikleri tek şey, Modeldir, ViewModel değil. Modeliniz sadece alan varlıkları değil, aynı zamanda iş mantığını da barındırmak zorunda. Açıkçası iş mantığı desteklemek zorundadır kullanıcı hikayelerinden biri arayacağım şeydir bir MemberEditTask: Olası seçenekler listesi (ve bunlardan biri olduğunu doğrulayarak, çünkü bu mantık Tüm Modeli aittir

public class MemberEditTask 
{ 
    private readonly Member _member; 

    public MemberEditTask(Member member, IRepository repository) 
    { 
     this._member = member; 
     this.StatusChoices = repository.GetPossibleMemberStatuses(member); 
    } 

    public ReadOnlyCollection<MemberStatus> StatusChoices { get; private set; } 

    public MemberStatus Status 
    { 
     get { return this._member.Status; } 
     set 
     { 
      if(!this.StatusChoices.Contains(value)) 
      { 
       throw new ArgumentOutOfRangeException(); 
      } 
      this._member.Status = value; 
     } 
    } 
} 

fiilen seçilmiş) iş mantığı ile tanımlanır. Ayrıca, bir FTP sunucusuna yüklenen bir dosyaya veya bir arka plan işlemine yanıt olarak sunucuda çalışan bir otomatik işlem gibi, MemberEditTask'u tüketen başka bir şeyi de hayal edebilirsiniz (belirli bir süre sonra durumu Etkin Değil olarak ayarlama).). Tüm bu şeylerin aynı iş kurallarını yerine getirmesi gerekiyor, bu yüzden hepsinin ortak olması gerekiyor (ViewModel'de değil).

Böylece sınıf göz önüne alındığında, ViewModel sınıf şuna benzer: sadece NotifyAllPropertiesChanged bir PropertyChanged yükseltmek yansıma kullanan ViewModelBase korunmuş bir yöntem olduğuna inanıyoruz, çok basit bir kolaylık olarak, bu durumda

public class MemberEditViewModel : ViewModelBase 
{ 
    private readonly MemberEditTask _task; 

    public MemberEditViewModel(MemberEditTask task) 
    { 
     this._task = task; 
    } 

    public IEnumerable<MemberStatus> StatusChoices 
     { get { return this._task.StatusChoices; } 

    public MemberStatus Status 
    { 
     get { return this._task.Status; } 
     set 
     { 
      this._task.Status = value; 
      NotifyAllPropertiesChanged(); 
     } 
    } 
} 

Olayı ViewModel'in tüm kamu özelliklerinde. :) Elbette overkill, ama daha önemli bir noktada ...

Bu neredeyse aptalca bir örnektir çünkü bu durumda MemberEditViewModel gereksizdir. Eğer Görünüm tek bir ayar olan Status ise, özellik değiştirilen etkinliği yükseltmeye gerek yok! Elbette gerçek dünyada daha fazla mülke sahip olacak ve etkileşimler olacak. ViewModel'in var olmasının nedeni, tüketiciye, görünümüyle ilgili özellikleri değiştiğinde bildirmektir; bu, Modelin yapmadığı bir şeydir (ve benim düşüncemde olmamalıdır). (ViewModel ayrıca animasyonları desteklemek için ekstra View-özel mantığa da sahiptir.)

Sorunuza geri dönelim ...Üyelik tarafından kullanılan bir hizmet olduğu için, MemberRepository'nin statülerden yararlanmanın yürütülmesinden sorumlu olup olmadığının ViewModel'in bakış açısından alakası yoktur. Model, ViewModel tarafından kullanılan bir hizmettir. Durum seçeneklerinin listesini sergilemek için görevinizi/iş akışınızı/sürecinizi/modelinizi yapın.

Üzgünüm, bu uzunca sarılmışsa.