Validierung

Gemäß dem Grundkonzept der Validierung kann die Validierung der Aggregate hinsichtlich unterschiedlicher Ausführungskontexte geprüft werden. Die Validierung der Aggregate bei der Persistierung hinsichtlich Konsistenz (vgl. Konsistenzgrenze Aggregate) ist allerdings bindend notwendig.

In der Domäne wird hierzu die Schnittstelle ISupportsValidation des Schleupen-Frameworks im AggregateRoot implementiert. Diese Klasse stellt die Konsistenz des Aggregats sicher. Die referenzierten Entitäten und ValueObjects validieren sich selber (OO!) und geben das Validierungsresultat zurück.

Der folgende Code zeigt beispielhaft eine Implementierung:

public partial class Buch : ISupportsValidation, ...
{
  ...
  public virtual ValidationResult ValidateRegardingPersistence()
  {
    var result = new ValidationResult();
    if (string.IsNullOrWhiteSpace(titel))
    {
      result.Add(BuchValidationMessage.CreateError(this, $"Das Buch mit der Id {Id.Value} muss einen Titel definiert haben."));
    }
    if (string.IsNullOrWhiteSpace(autor))
    {
      result.Add(BuchValidationMessage.CreateError(this, $"Das Buch mit der Id {Id.Value} muss einen Autor definiert haben."));
    }
    ...
    if (inhaltsangabe != null)
    {
      result.Merge(inhaltsangabe.ValidateRegardingPersistence(this));
    }
    return result;
  }
}

Wir fassen Validierung als Teil der Domänenlogik auf und das Externalisieren von Prüfungen wie bei FluentValidation vorgeschlagen, bricht die Kapselung auf, so dass alle Propertys per se öffentlich gemacht werden müssten. Daher sollte die Validierung mit dieser Bibliothek i.A. als nested-class implementiert werden.

Verwendet man die Basisklasse Repository<TAggregateRoot, TKey> des Schleupen-Frameworks, so ist keine weitere Einstellung zur Anbindung der Validierung vorzunehmen. Es wird die späte Validierung beim Aufruf von Flush() des Repositorys automatisch angewendet.

Frühe Validierung wird auf Serviceebene definiert und implementiert. Diese wird beispielsweise in den Benutzeroberflächen angeschlossen (siehe hierzu Validierung). Die Presentation-Engine ist hier explizit darauf vorbereitet. Die Implementierung einer Service-Operation zur frühen Validierung zeigt folgender Code:

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[ErrorHandlerBehavior(typeof(IdempotentOperationPendingFaultAssembler<IdempotentOperationPendingFaultContract>),
            typeof(ValidationFaultAssembler),
            typeof(UnhandledFaultAssembler<UnhandledFaultContract>))]
public class BuecherAusleihenActivityService : IBuecherAusleihenActivityService
{
    ...
  [IdempotentOperationBehavior]
  public virtual async Task<ValidateAusleihenResponse> ValidateAusleihenAsync(ValidateAusleihenRequest request)
  {
    if (request == null) { throw new ArgumentNullException(nameof(request)); }
    IEnumerable<BuchId> buecher = buchAssembler.ToDomainObjectIds(request.Buecher);
    ValidationResult validationResult = await leiheBuecherAusController.ValidateRegardingAusleihenAsync(new Sid(authenticationProvider.SessionCreatorSid), buecher);
    return new ValidateAusleihenResponse(validationResultAssembler.ToDataContract(validationResult));
  }
}

Frühe und späte Validierung hinsichtlich anderer Kontexte werden äquivalent implementiert.

Cookie Consent mit Real Cookie Banner