Ich verwende WCF nur für Datendienste (dh innerhalb der Anwendung und sehr schlank ohne Sitzungsstatus usw.), um unsere Webanwendung skalierbar zu halten.
Wir müssen einige allgemeine Eigenschaften für jeden Serviceanruf bereitstellen, an dem wir gerade die ganze Zeit vorbeikommen. Es ist nicht ideal, einzelne Request-Objekte für jeden Aufruf zu haben, denn jenseits dieser gemeinsamen Eigenschaften ist der Rest sehr unterschiedlich und ändert sich während der Entwicklung ziemlich häufig.
Momentan überlege ich, benutzerdefinierte Header und den clientmessage -Inspector zu verwenden, um die Werte festzulegen. Ist dies der einfachste empfohlene Ansatz für dieses Szenario oder gibt es einen besseren Ansatz?
Weitere Details ..
Die roten Punkte unten sind, wo ich unsicher bin, die richtige Annäherung (oder wie man darüber geht).
Was gesendet wird
Bei den gesendeten Daten handelt es sich um einfache IDs (3 oder 4 für Benutzer-ID, Client-ID usw.). Alle diese IDs wirken sich auf die Sicherheit und die Leistung aus (in einigen Fällen wird festgelegt, welche Datenbank verwendet wird) >
Wir werden dies auch erweitern, um komplexere Berechtigungen zu haben - die für die Windows Worker nicht benötigt werden.
Der Aufrufer ist entweder eine Webanwendung, in der diese aus einem Sitzungsobjekt stammen, oder ein Windows-Service-Mitarbeiter, der diese manuell füllt.
Das aktuelle Denken
Im Idealfall würde getInstance für den Workflow des Aufrufers diese Eigenschaften entweder automatisch mit dem Sitzungsobjekt oder mehr manuell mit den Windows-Serviceaufrufen füllen (andere Konstruktoren?).
Wir würden dann sicherstellen, dass diese Parameter immer ohne jeden Gedanken oder ohne konstante Referenzen im gesamten Code verfügbar sind, um den Vertrag für jede Funktion, die ihn aufruft, zu konstruieren. Wir haben derzeit viele Serviceanrufe (aufgrund der Skalierung / Komplexität der App, nicht aufgrund von schlechtem Engineering :)), da dies für komplexe Berechtigungen gilt, wird es ein bisschen schwierig, Regeln auf selbstdokumentierende Weise durchzusetzen / p>
Im Prinzip ist dies die Sitzung, in der Sie sich in der App darum kümmern, aber die Dienste sind eigentlich nur eine Datenzugriffsebene (mit Ansichtenzuordnung, Seitenaufruf und letzter Anrufsicherheit aus Repository-Aufrufen), also brauchen wir das nicht Art der Wiederholung oder Komplexität, nur die Schlüsselidentität & amp; Berechtigungsfelder für Abfragen.
Das Problem
Das ist sehr ähnlich wie etwas, das wir mit Headern bei den Aufrufen machen sollten, da wir diese Felder immer brauchen, aber ich bin mir nicht ganz sicher, wo das Set und das get im Lebenszyklus des Endpunkts und der Client-Schnittstelle sitzen sollten . Ich bin auch froh darüber falsch zu liegen.
Ich habe eine ähnliche Architektur angewendet; Grundsätzlich muss jeder Client-Aufruf Informationen darüber enthalten, welche DB ausgewählt werden soll, eine Kennung usw. Auf der Serverseite sollen diese Parameter automatisch verarbeitet und in einem Wörterbuch gespeichert werden.
Ich habe eine generische Proxy-Klasse erstellt, um Client-Proxies zu umschließen, um jedem Service-Aufruf verwandte Header hinzuzufügen. Jeder Entwickler, der einen Dienst aufrufen muss, hat diese generische Proxy-Klasse in seinen Aufrufen verwendet.
Auf der Dienstseite habe ich DispatchMessageInspector
als Endpunktverhalten implementiert, wobei Daten aus Anforderungsheadern extrahiert und in einem Wörterbuch gespeichert werden. Das Wörterbuch wird innerhalb einer Erweiterung von OperationContext ( IExtension<OperationContext>
) initialisiert und steht während der Anfrageverarbeitung zur Verfügung.
Beachten Sie, dass der Instanzkontextmodus von Diensten PerCall
ist.
Nach meiner Erfahrung kann die Verwendung von Nachrichtenspeichern sehr schwierig sein, um sie einzurichten und zu konfigurieren, und in meiner Recherche gab es keine Website, die alles abdeckte, ich musste Ausschnitte aus verschiedenen Orten auswählen und alles zusammenfügen.
>Sie müssen hinterfragen, was Sie in die Header eingeben. Sind es Informationen, die der aufgerufenen Methode zur Verfügung stehen müssen? Wenn dies der Fall ist, ist es falsch, sie in die Header einzufügen, da jede Methode die Informationen erneut analysieren muss.
Die Art von Information, die dafür ideal ist, sind benutzerdefinierte Authentifizierung und / oder benutzerspezifische Metadaten in Bezug auf den WCF-Aufruf. In meinem Fall hatte ich einen WCF-Anruf, der von einem automatisierten Dienst initiiert wurde, der an weitere WCF-Endpunkte weitergeleitet wurde. Dies war ein ideales Szenario für die Verwendung von Nachrichteninspektoren, da ich Metadaten zu den Kopfzeilen an den Weiterleitungspunkten hinzufügen konnte Endpunkt.
Wenn Sie nur einige Daten sammeln möchten, die jedem Aufruf gemeinsam sind, dann würde ich ein Basisdatenobjekt mit den entsprechenden Eigenschaften hinzufügen und es dann für die spezielleren Aufrufe erweitern (der Endpunkt kann sicherstellen, dass es funktioniert) dass gemeinsame Daten entweder vorhanden sind oder einige Standardwerte annehmen, wenn dies nicht der Fall ist). Für allgemeine Daten, die von jedem Endpunkt benötigt werden, ist die Verwendung von Nachrichteninspektoren übertrieben und möglicherweise nicht durchführbar.
Dies könnte ein älterer Ansatz sein, aber Sie können CallContext leicht nutzen von System.Runtime.Remoting.Messaging
. Der Client könnte eine Implementierung von IClientMessageInspector
verwenden, um den Aufrufkontext beim Aufruf der Operation festzulegen, und eine Implementierung IMessageInspector
auf dem Server, um die freigegebenen Daten von CallContext
abzurufen.