Muster: Anschluss Domäne an Service-Fassade
Dieses Dokument definiert, wie eine Service-Fassade implementiert und an die Programmlogik eines Domänenmodells delegiert wird.
Design
Die Service-Fassade nimmt die durch Kamoto) übergeben, der die eigentliche Logik schließlich implementiert.
Die Service-Fassade nimmt die durch Kamoto generierten Datenverträge entgegen und übersetzt diese mittels Assembler in Domänenobjekte. Diese werden an einen UseCase-Controller (siehe Usecase-Controller) übergeben, der die eigentliche Logik schließlich implementiert.
Die Service-Fassade wird als Webservice-Klasse gemäß in der Services-Assembly implementiert.
Implementierung
Die Klasse einer Service-Fassade muss so heißen wie die Schittstelle (ohne das I
), damit die Dependency Injection via Castle funktioniert.
Die Anfragen werden an den Controller ManageBookCollectionController
delegiert.
[ServiceBehavior(IncludeExceptionDetailInFaults = true, TransactionIsolationLevel = IsolationLevel.ReadCommitted)] [ErrorHandlerBehavior(typeof(BuchServiceFaultAssembler), typeof(UnhandledFaultAssembler<UnhandledFaultContract>))] public sealed class BuecherAusleihenActivityService : IBuecherAusleihenActivityService { private IBuecherAusleihenController buecherAusleihenController; // ... public BuecherAusleihenActivityService(IBuecherAusleihenController buecherAusleihenController) { if (buecherAusleihenController == null) { throw new ArgumentNullException(nameof(buecherAusleihenController)); } this.controller = controller; } [OperationBehavior(TransactionScopeRequired = true)] public ExecuteResponse Execute(ExecuteRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } Guid[] buecher = request.Buecher.ToArray(); Ausleihe ausleihe = buecherAusleihenController.LeiheAus(... buecher); AusleiheContract ausleiheContract = ausleiheAssembler.ToDataContract(ausleihe); return new ExecuteResponse(ausleiheContract); } }
Dabei sollte die folgende Reihenfolge verwendet werden:
- Übersetzen von Datenvertrag in Domänenobjekt.
- Delegation der Aufgabe an den UseCase-Controller.
- Übersetzen von Domänenobjekt in Datenvertrag.
Fehlerbehandlung
Für Optimistic Locking existiert ein Schleupen.CS.PI.Framework.Services.ErrorHandling.StaleDataAssembler
. Dieser wird zusätzlich zu dem bereits existierenden FaultAssembler
angegeben.
Für das Optimistic Locking muss die Version-Eigenschaft von Datenvertrag zu Domänenobjekt und umgekehrt transportiert werden. Dieses darf nicht geändert werden.
Die Reihenfolge dabei ist so, dass der UnhandledFaultAssembler
als letzter angegeben werden muss.
[ErrorHandlerBehavior(typeof(StaleDataAssembler<StaleDataFaultContract>), typeof(UnhandledFaultAssembler<UnhandledFaultContract>))]
Sofern der Typ der Id-Property im Domänenobjekt abweichend vom Default System.Guid
gewählt wird - z.B. als ValueObject-Typ MyEntityId
- muss er in der Variante des StaleDateAssembler
mit zwei generischen Typ-Parametern als zweiter Parameter angegeben werden:
[ErrorHandlerBehavior(typeof(StaleDataAssembler<StaleDataFaultContract, MyEntityId>), typeof(UnhandledFaultAssembler<UnhandledFaultContract>))]
Der Typ MyEntityId
muss hierzu die Schnittstellen IEntityIdData
und IEquatable<MyEntityId>
implementieren.