2 Stimmen

Wie lade ich Module dynamisch in Prism / Composite Application Library?

Ich habe eine Klasse in meiner Prism/CAL-Anwendung, die ein Formular generiert , in das Benutzer Daten eingeben können.

Das Formular wird von einer XML Datei wie folgt definiert:

                Anrede
                Anrede

                Vorname
                Text

                Nachname
                Text

                E-Mail
                E-Mail

            ...

Das Formular muss spezifische Steuerelemente laden, die jedem Feldtyp im XML entsprechen, z.B.

  • Anrede (zeigt ein Dropdown-Menü: Herr, Frau, Dr., usw.)
  • Text (einfaches Textfeld)
  • E-Mail (Textfeld mit E-Mail-Validierung)
  • PLZ (Textfeld mit Postleitzahlen-Validierung)

Ich möchte jedes Steuerelement zu einem separaten Modul machen, das geladen wird, sodass z.B. das PLZ Modul als Datei im Modules Verzeichnis existieren würde:

PLZ.dll

das nur ein einfaches Textfeld Steuerelement ist, das anhand der Postleitzahl validiert, aber Entwickler könnten ein weiteres Steuerelement namens:

PLZPlus.dll

erstellen, das die gleiche Schnittstelle erbt, aber einen Popup-Geo-Earth-Selektor für Postleitzahlen bereitstellt. Sobald ein Kunde PLZ.dll durch PLZPlus.dll ersetzt, hätten alle seine Formulare diese neue Funktionalität zur Suche nach Postleitzahlen.

Ich habe jedoch Schwierigkeiten zu visualisieren, wie dies technisch umgesetzt wird, da meine Formklasse beim Parsen des XML die Klassen instanziiert, die die Funktionalität für die Steuerelemente bereitstellen, aber um die Klasse zu instancieren, muss ich eine Referenz dazu haben:

SmartFormFieldPLZPresenter smartFormFieldEmailPresenter
    = container.Resolve();

Wie kann ich es jedoch dynamisch instanziieren, d.h. mit dem Klassennamen als String, und wenn diese Klasse nicht existiert, eine entsprechende Ausnahme auslösen, z.B. so etwas wie:

PSEUDO-CODE:

try {
    var smartFormFieldPLZPresenter
        = container.Resolve("smartFormFieldPLZPresenter");
}
catch (ModulExistiertNichtException) {
    ...
}

3voto

Brad Leach Punkte 16577

Es scheint, dass du sehr nahe an einer technischen Lösung für dein Problem bist. Ich würde einfach eine Schnittstelle - IZipCodePresenter - erstellen und in meinem ZipCode.dll- oder ZipCodePlus.dll-Modul-Startup die Implementierung registrieren.

Container.RegisterType();

Dann löse in deinem Parser die Instanz wie folgt auf:

var zipCodePresenter = container.Resolve();

Anzunehmen ist, dass keine Instanzen für die Schnittstelle registriert sind, wird eine Ausnahme geworfen. Andernfalls erhältst du die zuletzt registrierte konkrete Implementierung von IZipCodePresenter. Beachte, dass eine Ausnahme nur geworfen wird, wenn du versuchst, eine Schnittstelle zu registrieren. Wenn du versuchst, eine Klasse mit Unity zu registrieren, wird eine Instanz basierend auf der Lebensdauer-Manager-Richtlinie erstellt.

Wenn du dies noch weiter vertiefen möchtest, könntest du eine Schnittstelle erstellen... so etwas wie IDynamicPresenter. Du könntest dann basierend auf einem bekannten String (definiert in deinem Infrastrukturprojekt) registrieren.

Container.RegisterType(PresenterName.ZipCodeControl);
Container.RegisterType(PresenterName.EmailControl);

und dann wie folgt auflösen:

var zipCodeControl = Container.Resolve(PresenterName.ZipCodeControl);
var emailControl = Container.Resolve(PresenterName.EmailControl);

Ich bevorzuge die erstere Lösung, aber dies ist sicherlich eine gültige Option.

Ich hoffe, das hilft!

P.s. Das klingt nach einer interessanten Idee... ich wäre interessiert zu hören, wie es mit der Umsetzung weitergeht. Du könntest sogar noch einen Schritt weiter gehen und ein ganzes XAML-Builder-Framework basierend auf einigen der Konzepte in ASP.NET MVC erstellen. Es könnte die Testbarkeit erleichtern und gleichzeitig die Leistung von WPF bieten. Viel Glück!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X