Hallo zusammen,
für meine Anwendung möchte ich Plugins breitstellen, in denen sich Views und ViewModels befinden. Wie sollte man dies am besten in die Tat umsetzen?
zero_x
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
Hallo Lector,
den von dir genannten Link, ist mir bekannt. Für mich ist es von Interesse, wie man ein Plugin-System mit dem MVVM-Pattern realisieren kann. Wie ein Plugin-System im Detail funktioniert, ist mir klar und nicht das Problem. Wie du auch aus meinem letzen bzw. ersten Beitrag entnehmen kannst, geht es mir um die ViewModels und View, die sich in dem Plugin befinden und mit der Client-Anwendung kommunizieren müssen.
zero_x
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
Hallo,
für ein Programm wo ich grad dran bin setzt ich das wie folgt um (bin noch an der Planung deshalb sind das alles nur Ideen und kann sein das die Implementierung dann noch irgend nen nicht bedachten Felsbrocken dazwischen wirft).
Und zwar verwende ich MEF (Managed Extensibility Framework). Das Programm exportiert die Modelobjekte welche dann von den Plugins importiert werden. Die Plugins haben dann ihre ViewModels welche die Daten durch die importierten Modelobjekte bekommen und ihre Views. Die Views wiederum werden als Pages realisiert und von den Plugins exportiert. Diese Views importiert das Hauptprogramm und kann sie dann in nen Frame z.B. anzeigen. Für die Anwendung die ich schreibe, sollte das prinzipiell funktionieren 😉 obs auch für deinen Anwendungsfall funktioniert weiß ich nicht.
Wichtig zu wissen ist noch das dass mit MEF dann eigentlich keine Plugins im eigentlichen Sinne sind, sondern man muss sich das eher so vorstellen das "Plugin"code und Hauptanwendung zur Laufzeit zu einer einzigen Anwendung gemergt werden. Deshalb kann man in der Anwendung einfach die Viewobjekte der Plugins benutzen und die Plugins können mit den Modelobjekten der Anwendung arbeiten. Trotzdem hat man die Möglichkeit die Plugins jederzeit wieder zu entladen und neue hinzuzufügen.
Durch die enge Verknüpfung von Model und ViewModel ist so ein klassisches Pluginmodel gar nicht so einfach umzusetzen wenn du in den Plugins nur ViewModels und Views haben möchtest.
Baka wa shinanakya naoranai.
Mein XING Profil.
Hallo talla,
wie du sagtest, verwendest du nicht das klassische Plugin-Model. Genau das ist mein Verständnisproblem. In meinen Augen kann man das klassische Plugin-Model für diesen Zweck nicht verwenden, da einerseits das DataBinding und andererseits das MVVM-Pattern den Plugins in die Quere kommen.
Kannst du mehr in Detail gehen bzw. wie hast du die Angelegenheit programmiert? Wie hat die Client-Anwendung Zugriff auf die Daten der Plugins und deren Models? Wie sind die Plugins im Allgemeinen aufgebaut?
zero_x
P.S.: Es wäre sehr nett, wenn du ein Stück Beispielcode posten könntest! =)
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
Hallo,
falls du es noch nicht kennst bringt dich das hier vielleicht weiter:Building an Extensible Application with MEF, WPF, and MVVM
Das funktioniert ausgezeichnet und ist relativ schnell zu durchschauen. Die Bewertungen sprechen auch für sich. Man kann die Library sehr leicht anpassen (z.B. das Physics2D rausnehmen) und sich somit seine eigene kleine aber feine Library basteln. Auf der im Artikel erwähnten Projekseite sind weitere Infos und ein WIKI.
Gruß
xbredoillex
Hallo zero_x,
ich habe es so umgesetzt. Die ViewModels und Views werden im Pugin-eigenen Ressource-Dict. definiert. Beim Starten des Host, lese ich alle Ressource-Files der Plugins ein und füge sie den Ressourcen des Host hinzu. Somit kennt der Host die Templates und kann sie anzeigen.
Hallo,
auf Nachfrage von zero_x mein Vorgehen etwas detaillierter:
Meine Anwendung lädt die Plugins 'klassisch' über Assembly.Load() ähnlich wie in diesem Projekt: http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx
Das 'MainViewModel' ist im Host definiert. Es kümmert sich um das Anzeigen der Workspaces (die u.a. in den Plugins implementiert sind). So wie im folgenden Beispiel: http://msdn.microsoft.com/de-de/magazine/dd419663.aspx
In den Plugins werden die ViewModels und Views implementiert. Jedes Plugin enthält eine Ressourcen-Datei (Resources.xaml). In dieser werden die DataTemplates definiert:
<ResourceDictionary>
...
<DataTemplate DataType="{x:Type viewmodel:DetailsViewModel}">
<view:DetailsView />
</DataTemplate>
</ResourceDictionary>
Beim Starten des Hosts, lädt dieser die Ressourcen-Dateien der Plugins (AssemblyNamePlugin + ";component/Resources.xaml") zu seinen eigenen Ressourcen hinzu:
ResourceDictionary resources
App.Current.Resources.MergedDictionaries.Add(resources);
Der Host stellt den Plugins u.a. einen Service zur Verfügung, über welchen die Plugins dann ihre Workspaces öffnen können:
public void Open(WorkspaceViewModel viewModel)
... das war es schon ..
Hallo cx°,
was genau ist im Plugin-Interface definiert und wie arbeitet das DataTemplate zusammen mit dem Host?
zero_x
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
mhhh. wenn du möchtest baue ich nächste woche mal eine demo-anwendung?
Hallo cx°,
das wäre sehr nett von dir! =)
zero_x
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
So, in der Anlage das angekündigte Beispiel. Ich habe die o.g. Projekte mal 'zusammengesteckt'. Nicht ganz sauber umgesetzt, aber soll ja nur den Weg zeigen...
Hallo cx°,
vielen Dank für das ausführliche Beispiel! Du bist einfach der Beste - Danke!! 🙂
zero_x
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
so, ich ich hatte mit zero_x ne kleine Diskussion, wie sinnvoll es ist, diverse Teile eines Projekts, an dem wir gemeinsam arbeiten, mit MVVM umzusetzen.
Da wäre zunächst mal die Frage, wie sinnvoll es ist, für die Aufteilung der Oberfläche MEF zu benutzen, wenn man wahrscheinlich nicht vor hat, die Oberfläche durch Plugins zu erweitern.
Dann wären da noch die Plugins: Sie fügen keine neuen Funktionen hinzu, sondern haben eigentlich nur 1 Klasse, die bestehende Funktionen auf anderen Onlinedienste erweitet und Einstellungsdialoge mit relativ wenigen Einstellungen.
Ich vertrete da eher die Meinung, dass beim ersten Fall das MEF n bisschen n Overkill wäre, da es so wie ich das verstanden hab dort um dieErweiterung der Anwendungen mit Plugins geht.
Und zum 2. Fall:
So wie ich das verstanden habe, nutzt man MVVM wenn man eine Datenquelle hat, die man visualisieren möchte (zum Beispiel in einer Liste anzeigen, mit angepassten Templates, wo man noch Werte verändern kann, ...). Das würde dann auf die Plugins allerdings nicht zutreffen und eigentlich auch nicht auf die Einstellungsdialoge der Plugins.
Wie seht ihr das? Gibts da generell die Empfehlung MVVM zu benutzen (auch zum Beispiel im HInblick auf Unit-Testing)?
Tobi