2010-12-08 8 views
5

Angenommen, ich habe zwei Ansichten in meiner App, MemberListView und MemberEditView. Sie sind mit ihren Perspektiven viewModels, MemberListViewModel und MemberEditViewModel verknüpft. Die Modelle sprechen mit einer Repository-Klasse, MemberRepository, die über die CRUD-Methoden für die Member-Klasse verfügt. In dem MemberEditView-Formular habe ich mehrere Dropdowns, die Thinkgs wie Status (Aktiv/Inaktiv/Ausstehend), den Handelscode der Mitglieder usw. anzeigen. Sie sind ObservableCollection-Objekte in meinem viewModel und sind an ComboBoxes in der Ansicht gebunden. Soll das MemberRepository die gets für das Abrufen der Listen von jedem, das angezeigt werden soll, behandeln?MVVM und Repository Frage

Was ist, wenn ich auf der MemberEditView ein Raster habe, das alle Jobs anzeigt, die das Mitglied im Laufe der Jahre gehabt hat. Wenn der Benutzer einen der Jobs doppelklickt, ruft er eine JobHistoryEditView auf, um die Jobinformation anzuzeigen, und er hat ein JobHistoryViewModel. Soll das MemberRepository sich um die JobHistory CRUD Methoden kümmern oder sollte ich ein separates JobHistory Repository haben?

Antwort

2

meisten MVVM Anwendungen würden diese Architektur haben:

View -> ViewModel -> Model -> Repository 

Ich habe espousing eine Variante vor kurzem:

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

(Wo A -> B bedeutet "A kennt B", aber B weiß nicht über A.)

Beachten Sie, dass in beiden Fällen das einzige, das über das Repository weiß, das Modell ist, nicht das ViewModel. Ihr Modell ist nicht nur die Domänen-Entitäten, sondern auch die Geschäftslogik. Offensichtlich eines der User Stories Ihre Geschäftslogik zu unterstützen hat, ist etwas, was ich nenne ein MemberEditTask:

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; 
     } 
    } 
} 

All diese Logik in Ihrem Modell gehört, weil die Liste der möglichen Entscheidungen (und Validierung, dass einer von denen war tatsächlich gewählt) wird durch Geschäftslogik definiert. Sie könnten sich auch eine andere Sache vorstellen, die MemberEditTask verbraucht, wie ein automatisierter Prozess auf dem Server, der ein Mitglied als Antwort auf eine auf einem FTP-Server hochgeladene Datei bearbeitet, oder einen Hintergrundprozess (den Status nach einer gewissen Zeit auf Inaktiv setzen)). All diese Dinge müssen die gleichen Geschäftsregeln ausführen, also muss alles gemeinsam sein (nicht im ViewModel).

diese Klasse So gegeben, sieht das Viewmodel Klasse wie folgt:

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(); 
     } 
    } 
} 

In diesem Fall als eine sehr einfache Bequemlichkeit, nur glauben, dass NotifyAllPropertiesChanged eine geschützte Methode von ViewModelBase ist die Reflexion verwendet ein PropertyChanged zu erhöhen Ereignis auf alle öffentlichen Eigenschaften des ViewModel. :) Das ist Overkill natürlich, aber es fährt an einem wichtigeren Punkt ...

Das ist fast ein dummer Beispiel, weil in diesem Fall MemberEditViewModel unnötig ist. Wenn die Ansicht die einzige Einstellung Status ist, dann ist es wirklich nicht notwendig, das Property geändertes Ereignis zu erhöhen! Natürlich werden Sie in der realen Welt mehr Eigenschaften haben und es wird Interaktionen geben. Der Grund für die Existenz des ViewModels besteht darin, die Verbraucher zu benachrichtigen, wenn sich ihre ansichtsbezogenen Eigenschaften ändern, was das Model nicht tut (und meiner Meinung nach nicht tun sollte). (Das ViewModel hat auch eine zusätzliche View-spezifische Logik zur Unterstützung von Animationen usw.)

Also zurück zu Ihrer Frage ...Ob das MemberRepository für das Ausführen der Abrufe der Status zuständig ist oder nicht, ist aus der Sicht des ViewModels irrelevant, da das Repository ein Service ist, der vom Model verwendet wird. Das Modell ist ein Service, der vom ViewModel verwendet wird. Machen Sie Ihr Modell der Aufgabe/Workflow/Prozess/was auch immer die Liste der Statusoptionen offen legen.

Sorry, wenn das langatmig war.