2 Stimmen

Validierung von Befehlen vor der Ausführung

In dem System, das ich derzeit aufbaue, verwende ich das Befehlsmuster, um alle möglichen Operationen auszuführen. Ich habe den CommandMessage- und CommandHandler-Ansatz gewählt, um die Logik von den Daten zu trennen. Das funktioniert im Moment gut, aber ich bin auf ein Problem gestoßen - die Validierung.

Wie kann ich überprüfen, ob ein Befehl ausgeführt werden kann oder nicht?

Im Moment habe ich eine CanExecute(ICommandExecutionContext context) auf jeden Befehl und ist somit dafür verantwortlich, ob er ausgeführt werden kann oder nicht. A ICommandExecutionContext wird dann in jedem Befehl geprüft, ob er vom richtigen Kontexttyp ist, und anschließend, ob die Information den Befehl in diesem Kontext ausführbar macht.

Alles ist verpackt in einem ICommandService die Befehle auf der Grundlage ihrer Namen, ihres Kontexts und ihrer Nachricht validieren und ausführen kann. Außerdem veröffentlicht es Ereignisse über die Befehlsausführung und führt Berechtigungsprüfungen durch.

Das Problem geht von der Benutzeroberfläche aus (eine ASP.NET MVC 3-Anwendung). Ich möchte in jeder Ansicht nur gültige Befehle anzeigen, aber ich habe keine Lösung gefunden, die mir wirklich gefällt. Derzeit fragt mein Controller den Befehlsdienst, ob ein Befehl ausgeführt werden kann, wenn ein konkreter Kontext wie folgt gegeben ist:

var executionContext = new SystemCommandExecutionContext("SignInCommand", CurrentPrincial);
var canExecute = _commandService.CanExecute(executionContext);
/* Handle the result to enable or disable the action link */

Für andere Arten von Befehlen, die mit konkreten Domänenobjekten funktionieren, verwende ich dieselbe Befehlsdienstmethode, aber in einem anderen Kontext, in dem ich die Domänenobjekt-ID übergebe, etwa so:

[HttpPost, Authorize, ValidateAntiForgeryToken /* etc. */]
public ActionResult Delete(Guid id)
{
    /* Note the additional object id in the context */
    var executionContext = new EntityCommandExecutionContext("DeletePersonCommand", CurrentPrincipal, id);
    var canExecute = _commandService.CanExecute(executionContext);

    if(canExecute)
    {
        var message = new DeletePersonCommandMessage(id);
        var isValid = _commandService.IsValid(executionContext, message);
        if(isValid)
        {
            var result = _commandService.Execute(executionContext, message);
            /* More logic here... Not very DRY :( */
        }            
    }
}

Ich denke, die obigen Angaben sind für den Moment in Ordnung, auch wenn sie nicht sehr trocken sind. Aber was ich erreichen möchte, ist die Aktion Links zu deaktivieren, basierend auf dem Ergebnis von CanExecute.

Wie kann ich das tun?

Ich habe beschlossen, alle Befehlsverknüpfungen in jeder Ansicht zu "hardcodieren", damit ich nicht eine Sammlung von Befehlsnamen usw. übergeben muss. - dieser Weg ist zu schwierig (es sei denn, jemand hat eine clevere Idee ;)

Mein aktueller Stack besteht aus NHibernate, Castle Windsor, ASP.NET MVC 3, AutoMapper.

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