Laden...

MVVM Architektur Frage -> wird das so gelöst?

Erstellt von 1nf1n1ty vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.304 Views
1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren
MVVM Architektur Frage -> wird das so gelöst?

Hallo zusammen,

ich habe nun mein erstes Projekt mit MVVM und habe diesbezüglich nun ein paar Fragen.

Ich habe eine MainView mit ViewModel, die einige Funktionen enthält (Toolbar, WebService Instanz/Connection) und zwei weitere (ich nenn sie mal) SubViews (ebenfalls mit je einem SubViewModel), die dazu dienen die Daten entsprechend darzustellen. Bei einer der beiden SubViews gibt es eine integrierte Suchfunktion, d.h. da diese SubView die Instanz des WebServices ja nicht kennt, müsste ich nun der MainView mitteilen, dass es Daten benötigt.

  1. Frage:
    Es ist ja gängige Praxis, dass es ein MainViewModel gibt, dass die SubViewModels kennt. Wäre es dann in Ordnung (oder ist es üblich), wenn ich im MainView Model das Result einer Anfrage direkt in das SubViewModel zu reichen? Durch das DataBinding werden die Daten dann ja sowieso dargestellt. Oder sollte man in MainViewModel ebenfalls eine Liste des gleichen Typ haben und dem SubViewModel quasi nur eine Referenz darauf mitteilen?

  2. Frage:
    SubViewModel2 hat eine Suchfunktion und fordert von MainViewModel Daten an. Meine erste Idee war es im SubViewModel ein Event anzubieten, welches das MainViewModel aboniert. Dort könnte man dann den Servicerequest machen und die zurückgekommenden Daten so wie in Frage 1 beschrieben an das ViewModel weiterreichen. Ich frage mich nun auch hier ob dies so üblich ist oder ob es einen anderen/besseren Weg hierfür gibt?

Vielen Dank für die Antworten und viele Grüße!

5.299 Beiträge seit 2008
vor 13 Jahren

(Vorab: Ich bin nicht wirklich WPF-Profi, und mit Patterns gehe ich sehr pragmatisch um, wenn nicht gar respektlos)

  1. Frage:
    Es ist ja gängige Praxis, dass es ein MainViewModel gibt, dass die SubViewModels kennt. Wäre es dann in Ordnung (oder ist es üblich), wenn ich im MainView Model das Result einer Anfrage direkt in das SubViewModel zu reichen?

Ja natürlich. Ich verstehe die ViewModelei als ein Abbild des Guis, und wenn das Gui ein Form mit einem UserControl ist, dann ist das Viewmodel eines mit einem SubViewModel. Und die Kommunikation ganz nach Schema F: Das Objekt kennt seine SubObjekte, und manipuliert deren Methoden, das SubObjekt kennt seinen Owner nicht, sondern sendet Events.

Durch das DataBinding werden die Daten dann ja sowieso dargestellt. Oder sollte man in MainViewModel ebenfalls eine Liste des gleichen Typ haben und dem SubViewModel quasi nur eine Referenz darauf mitteilen?

"Eine Referenz mitteilen" ist bisserl komisch formuliert. "Ebenfalls eine Liste haben" klingt nach redundanter Datenhaltung, und das ist eindeutig böse.

  1. Frage:
    SubViewModel2 hat eine Suchfunktion und fordert von MainViewModel Daten an. Meine erste Idee war es im SubViewModel ein Event anzubieten, welches das MainViewModel aboniert. Dort könnte man dann den Servicerequest machen und die zurückgekommenden Daten so wie in Frage 1 beschrieben an das ViewModel weiterreichen. Ich frage mich nun auch hier ob dies so üblich ist oder ob es einen anderen/besseren Weg hierfür gibt?

Ich wüsste zunächst mal auch nix anneres. Höchstens, ob es wirklich das SubModel sein muß mit der Suchfunktion, oder ob die nicht ins MainModel gehört.

Der frühe Apfel fängt den Wurm.

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren

Hi und vielen Dank schonmal.


Ich wüsste zunächst mal auch nix anneres. Höchstens, ob es wirklich das SubModel sein muß mit der Suchfunktion, oder ob die nicht ins MainModel gehört. 

In dem Fall muss es wohl so sein. Der eigentliche Serviceaufruf (laden der Daten) ist natürlich im MainViewModel untergebracht, aber die Anforderung dafür gibt der Benutzer (Parameter festlegen und über Button die Anforderung stellen). Meine Idee war hier ein RequestSearchEvent, das als Eventparameter die in der SubView eingestellen Parameter beinhaltet und zur Suche dienen. Diese könnten dann im MainViewModel ausgewertet und an den Service weitergeleitet werden, der dann eine Liste zurückschickt. Diese würde ich dann an das SubViewModel weiterreichen.

Dadurch habe ich aber ja wiederum eine Abhängigkeit drin, bzw. muss mich darauf verlassen, dass der jenige, der die Funktion verwendet das Event 1. aboniert und dann 2. die Daten in die richtige Liste ins SubViewModel packt. Deswegen habe ich mich gefragt ob das so das übliche vorgehen ist oder das hier besser gelöst werden kann.

Viele Grüße

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo 1nf1n1ty,

das MVVM-Pattern ist sehr flexibel. Man kann ein Problem auf mehreren Arten lösen. Der eine macht das so, der Andere so. Das Problem ist einfach, dass man sich fragen sollte, wie man es am besten umsetzt. Das ist jedenfalls meine Meinung dazu.

So wie ich das sehe hast du das Problem, dass du eine Kommunikation zwischen den ViewModel brauchst. Ein Mediator oder EventAggregator würde das lösen können. Du könntest noch einen Schritt weitergehen und die ViewModels durch einen IoC/DI-Container leiten. Die ViewModel kannst du dann auch ein Stück weit abstrahieren. So kansnt du dann sagen, ob du eine neue Instanz oder die gleiche Instanz(Singleton, Monoton) haben möchtest.

Beachte bitte, dass es mehrere Herangehensweisen gibt. Darauf möchte ich jetzt nicht weiter drauf eingehen, sondern dich auf diesen Arikel aufmerksam machen. Dort ist es ganz gut beschrieben. Wie genau hast du das bei der zweiten Frage gelöst?

Für mich sind deine Aussagen/Fragen zu schwammig und sehr oberflächlich. Kannst du ein konkreteres Beispiel nennen? Beispielcode wäre auch ganz nett.

zero_x

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren

Hi,

Code dazu gibt es noch nicht. Ich habe mir nur beim Entwickeln diese Gedanken gemacht und mich gefragt ob das gut ist. Vorgestellt habe ichs mir etwa so:


//PSeudoCode aufs wesentliche beschränkt

//SubViewModel:

//Liste, gebunden
public Observable<DisplayData> DisplayDataList {get; set;}

//Event, das für die Suche aboniert werden muss
public event RequestSearchEvent;

//Suchmethode, wird von Benutzer über Button angestoßen
public void SearchData() 
{
    //ggf. noch irgendwas machen

    //Event feuern
    if(RequestSearchEvent != null)
        RequestSearchEvent(this, new SearchParameter { Name="meine Suche", Option=1});
}


//MainViewModel:

//Feld des SubViewModels
private SubViewModel subViewModel;

//Ctor
public MainViewModel 
{
    subViewModel.RequestSearchEvent += SubViewModelRequestSearchEvent;
}

//Eventmethode vom SubViewModel
public void SubViewModelRequestSearchEvent(object sender, SearchEventArgs e) 
{
    webserviceClient.GetDataAsync(e.Name, e.Addition);
}

//Completed Handler vom WebService
public void GetDataCompleted(object sender, GetDataEventArgs e)
{
    subViewModel.DisplayData = e.Result;
}


Das war meine Idee. Ich zweifle aber aus oben genannten Gründen immernoch daran, das dies eine gängige/gute Lösung ist.