Hallo zusammen, ich habe auf meine Webservice-Infrastruktur einen zusätzlichen Layer gebastelt, um die Webdienste konform zu einem Industriestandard zu machen. Ich bin gerade dabei, diese Schicht zu überarbeiten. U.a. gibt es eine Execute-Methode, welche abhängig von einem Parameter einen bestimmten Webdienst ausführt und das Ergebnis an einen Client zurückliefert. Bisher mache ich das über einen Switch/case, also ungefähr so:
C#-Code:
public void Execute( ref WPSProcess process ) { switch( process.ProcessBriefType.Identifier.Text ) { case "Gelaendeinfo": ExecuteGelaendeinfo( ref process ); break; case "GW-Basis": ExecuteGWBasis( ref process ); break; case "Gelaendeprofil": ExecuteGelaendeprofil( ref process, false ); break; //... } }
// Anschließend folgt die Implementierung der einzelnen Execute-Methoden private void ExecuteGelaendeinfo(ref WPSProcess process) { // hier wird der Webdienst aufgerufen... }
Das funktioniert zwar, ist aber sicher nicht die eleganteste Vorgehensweise. Kennt jemand ein gutes Muster, wie man so etwas implementieren kann? Da immer wieder neue Webdienste hinzukommen, spielt natürlich der Aspekt der flexiblen Erweiterung eine große Rolle. Ich lese gerade ein Buch zum Thema Entwurfsmuster und bin gerade beim Factory-Pattern. Könnte mir vorstellen, dass man dieses Muster hierfür verwenden kann. Aber ich bin noch nicht durch mit dem Buch, gibt es evtl bessere Muster oder Konzepte? Wäre dankbar für einen Tipp!
grob zusammengefasst ist das so: Wir haben Geofunktionen, welche wir bisher über eine XML-Webservice-Schicht bereitgestellt haben. Nun habe ich eine weitere Schicht erstellt, um diese Dienste einem neuen Geo-Standard konform zu machen. Die Methoden oben werden nur intern in dieser Schnittstelle genutzt um die bestehenden XML Webservices aufzufrufen und sind kein Endpunkt nach außen. Ich frage mich nur, ob es nicht eine generischere Variante wie das switch/case gibt. Vielleicht schaue ich mir noch mal das Strategy-Muster an, wie von Matthias vorgeschlagen.
So ganz überblicke ich nicht, was Du da genau vorhast. Aber ein möglicher Kandidat, um switch-case-Verzweigungen loszuwerden, ist das Strategie-Muster.
ich habe es mal mit einer Art "Hashed Adapter Objects" (Pattern) versucht:
Aufbau:
Interface
Jede Methode aus dem switch Statement wird in einem Objekt bereitgestellt, das das Interface implementiert
Factory, die ein Dictionary der Objekte hält
Die Factory instanziert beim Aufruf das entsprechende Objekt, und führt die Interface Method aus (Execute = Methode aus dem switch)
Nutzen: Für neue Services muss nur ein neuer Typ angelegt werden, der von IExecute ableitet, sowie der Konstruktor der Factory Klasse um einen Eintrag ergänzt werden.
class Service { public void Execute(ref WPSProcess process) { Factory.Execute(process); } }
Obige Version verwendet Reflection, um den Konstruktor aufzurufen, eine andere Variante wäre:
class Factory { private static Dictionary<string, IExecute> actions = new Dictionary<string, IExecute>(); private static Factory _instance = new Factory();
public static IExecute GetInstance(string processInfoText) { return actions[processInfoText]; }
private Factory() { actions.Add("GelaendeInfo", new GelaendeInfo()); actions.Add("GWBasis", new GWBasis()); actions.Add("Gelaendeprofil", new Gelaendeprofil()); } }
class Service { public void Execute(ref WPSProcess process) { Factory.GetInstance(process.ProcessBriefType.Identifier.Text).Execute(process); } }
Weitere Varianten sind denkbar, eventuell macht auch ein Implementieren von IDisposable auf den Objekten Sinn, andererseits wenn sie keine Daten halten kann man die Execute Methode auch ohne Interface als static implementieren und diese mittels Reflection aufrufen...
Hallo Maria, guter Ansatz. Ich denke Deine Vorgehensweise über den Action-Delegate ist ein guter Ansatz. Bin gerade dabei, das umzusetzen. Vielen Dank für Deine Ideen!