2016-04-22 3 views
3

Ich habe eine einfache Datenbankanwendung, in der ein Benutzer Personen hinzufügen oder löschen kann. Darüber hinaus verfügt die Anwendung über eine Schaltfläche "Hinzufügen neuer Schaltfläche zur Anwendung". Diese Anwendung wird unter Verwendung von Prism Framework erstellt. Es gibt zwei Module:Erstellen von Add-ons für WPF-Anwendungen

  • RibbonControlModule (enthält drei Tasten - Add Person, Delete Person, Add new button to application)

  • PersonModule (enthält Logik zum Hinzufügen und Löschen von Personen)

Meine Anforderung besteht darin, zur Laufzeit neue Schaltflächen hinzuzufügen.

Stellen wir uns eine Situation vor. Ich lebe in Washington und bin glücklich mit diesen beiden Tasten (Add Person und Delete Person). Aber mein Freund, Bob, der in New Jersey lebt, würde gern den neuen Knopf Edit Button hinzufügen, ohne die gesamte Anwendung neu zu kompilieren. Das heißt, Bob schreibt DLL, wo er Person bearbeiten kann und klickt dann Add new button to application in RibbonControlModule. Danach erscheint EditPerson Schaltfläche in RibbonControl und zum Beispiel in ContextMenu. Vielleicht EditPerson dll wäre ein anderes Prism-Modul, ich weiß es nicht.

Das heißt, meine Anforderungen sind:

  • steckbare Kontrollen
  • ist es möglich, eine Steuerung ohne recompliation Anschluss? (Wie Add-ons oder Erweiterungen (Classic Notes for Opera) in Browser (keine Notwendigkeit, einen Browser neu starten verwenden Add-ons))
  • andere Programmierer können ihre Add-ons entwickeln, ohne meinen Quellcode mit
  • nachdem einmal ein Benutzer eingesteckt ein Steuerelement, dann sollte dieses neue Steuerelement immer in der Anwendung eingesteckt sein.

Ist es möglich, WPF, MVVM und Prism zu verwenden? Ich mag Prism sehr und möchte Prism nicht leugnen, aber wenn "das Ende die Mittel heilt", würde ich gerne andere Technologien verwenden.

Wenn es möglich ist, wie kann ich es dann tun?

+0

Eine andere Alternative ist, dass ein Plugin die Implementierung einer Repräsentation einer Schaltfläche, die von Ihnen in einer Schnittstelle definiert ist, verfügbar macht. Sie werden wissen, wie Sie dies an die Benutzeroberfläche binden können, während Sie die Schnittstelle geschrieben haben. Werfen Sie die Implementierung in ein ContentControl und verwenden Sie eine DataTemplate, um das Steuerelement einzurichten, sei es eine Schaltfläche oder ein Dropdown oder irgendetwas. – Will

+0

@Will könnten Sie einen Link zur Verfügung stellen? – StepUp

+0

Beachten Sie, dass Sie in der Regel keine MEF oder ein anderes Framework dafür benötigen, wenn Sie sie nicht verwenden möchten. Sie definieren nur eine Schnittstelle (IModule), die von Add-In-Entwicklern implementiert wird, und Sie durchsuchen Assemblys nach Implementierungen dieser Schnittstelle, instanziieren und ausführen dann. Natürlich müssen Sie Erweiterungspunkte in der gesamten Anwendung definieren, aber Sie müssen das sowieso mit jedem Framework tun. – Evk

Antwort

3

Dies ist, was die MEF plugin architecture für entwickelt wurde.

Kurz gesagt, Sie erstellen ein SDK mit einer Schnittstelle für Ihre Plugins und stellen diese Ihren Kunden als eigenständige Bibliothek zur Verfügung. Die Plugins Ihres Clients implementieren dann diese Schnittstelle und exportieren sie mit dem Attribut MEF Export, das Ihre Hauptanwendung dann importiert.

Wo es ein wenig schwierig wird, ist mit Datentemplating, die oft eine Schlüsselkomponente von MVVM ist. Um es kurz zu machen: Ihre Plugins müssen ihre Datenvorlagen in ein Ressourcenwörterbuch stellen, dem Wörterbuch eine eigene partielle Klassendatei geben und sie mit dem Attribut [Export] von MEF exportieren. Ihre Hauptanwendung muss diese dann importieren und sie dem Array "MergedDictionaries" des globalen ResourceDictionary hinzufügen. Dies geschieht im Allgemeinen getrennt von all Ihren Ansichtsmodellklassen, die in einem separaten Durchgang importiert werden.Der Nettoeffekt ist, dass Ihre Plugins sowohl Ansichten als auch Ansichtsmodelle zur Laufzeit bereitstellen können, plus die Datenvorlagen, die die beiden miteinander verbinden, und alles funktioniert so, als wären sie statisch in Ihre ursprüngliche Anwendung kompiliert worden. Es bedeutet auch, dass Sie eine Plugin-API für Ihre Kunden erstellen können, ohne die Interna Ihrer Hauptanwendung offen legen zu müssen.

Dies ist ein sehr kompliziertes Thema, und angesichts der allgemeinen Frage ist ich überrascht, wenn diese Frage nicht markiert ist. Wenn Sie mehr Details wünschen, lassen Sie es mich wissen und wir können es auf eine Diskussionsseite verschieben.

+0

@StepUp Eigentlich habe ich noch nie selbst eine erstellt, nur die Links anderer Leute gefolgt. Versuchen Sie [diesen Link hier] (http://chat.stackoverflow.com/rooms/109889/mef-plugins-for-mvvm) und lassen Sie mich wissen, wenn Sie irgendwelche Probleme haben. –

2

Sie können das, was Sie beschreiben, mit Regions in Prism tun. Sie können Ihrer Multifunktionsleiste eine benannte Region hinzufügen, die es Prism-Modulen ermöglicht, neue Schaltflächen in diese Region einzubinden, wenn das Modul zum ersten Mal geladen wird oder später, wenn ein Benutzer auf eine Schaltfläche in einer Benutzeroberfläche Ihres Moduls klickt.

Fügen Sie dazu ein ItemsControl in einen Bereich in der Multifunktionsleiste ein, in dem die eingesteckten Steuerelemente angezeigt werden sollen. Fügen Sie das Prisma-Namespace als ein XAML-Namespace wie folgt:

prism:RegionManager.RegionName="CustomModuleCommandRegion"

Dann in Ihrem Modul, injizieren IRegionManager entweder im Modul:

xmlns:prism="http://prismlibrary/"

dann die folgenden angefügten Eigenschaft zu Ihrem Items hinzufügen Klasse selbst, wenn die Befehle hinzugefügt werden sollen, sobald das Modul geladen ist, oder an einer anderen Stelle in einem ViewModel, wenn es nicht vor dem Laden einer bestimmten Ansicht oder einer Benutzerinteraktion wie der von Ihnen beschriebenen auftritt:

Sie können auch die RegisterViewWithRegion-Methode des Regionsmanagers verwenden, um eine Factory-Methode einzurichten oder einfach den Typ der Schaltfläche), die Sie injizieren möchten. Aber für eine Schaltfläche müssen Sie einen Befehlshandler verdrahten, bevor (oder nachdem) Sie ihn in der Region platzieren, so dass AddViewToRegion wahrscheinlich geeigneter ist. Wenn es sich um einen Kontext handelt, der kontextsensitiv ist - dh die Schaltfläche soll nur in der Multifunktionsleiste angezeigt werden, wenn in einer Ansicht eine Auswahl getroffen wird - dann können Sie zuerst die Region vom Regionsmanager abrufen und dann die Add und verwenden dh diese neue Funktionalität könnte „fiel in“ -

IRegion region = _regionManager.Regions["CustomModuleCommandRegion"]; 
region.Add(myCommandView); 
... 
region.Remove(myCommandView); 

mit der Kombination von Prism-Module und Regionen Sie können Laufzeit Erweiterbarkeit der App erreichen: Methoden auf IRegion zu Ihrer Ansicht (Button) dynamisch wie so hinzufügen und entfernen ohne die Haupt-App oder andere Module in der App neu kompilieren zu müssen. Dazu müssen Sie entweder die Konfiguration verwenden, um Ihre Module anzugeben, sodass sie in der implementierten Umgebung bearbeitet werden können, um ein Modul hinzuzufügen, oder Sie können DirectoryModuleCatalog verwenden, um ein Verzeichnis nach Modulen beim Start zu durchsuchen. Es ist sogar möglich, einen FileSystemWatcher zu verwenden, um ein Verzeichnis nach Modulen zu sehen, die während der Ausführung der App eingeworfen werden und sie sofort aufleuchten lassen, wenn sie im überwachten Verzeichnis abgelegt werden.

+0

Vielen Dank für Ihre Antwort, Brian. Vielen Dank. Aber es scheint mir, dass "MEF" für die beschriebenen Situationen entwickelt wurde und es besser anwendbar ist. Ist es richtig? und es ist eine klarere Architektur für steckbare Software? – StepUp

Verwandte Themen