2009-08-24 6 views
2

Ich versuche, Entwicklern zu erlauben, meinen Code an bestimmten Punkten der Ausführung zu erweitern.Entwurfsmuster, um Code an bestimmten Punkten injizieren zu lassen

Mein spezifisches Beispiel ist ein Datenbank-Transaktions-Wrapper. Der Wrapper kümmert sich um viele Details, die wir vom Entwickler abstrahieren wollten und wird in mehreren Projekten verwendet.

Jedes Projekt hat jedoch bestimmte Dinge, die sie während der Transaktion automatisch tun möchten. Ich möchte Interception-Punkte hinzufügen, die jedes Projekt zum Ausführen von Code einrichten kann.

Zum Beispiel hat jede Tabelle in unserer Datenbank ein Eingabedatum Feld, das jedes Mal aktualisiert wird, wenn sich der Datensatz ändert. Wir möchten jedoch, dass alle Daten für eine Transaktion gleich sind, obwohl viele Datensätze berührt werden (d. H. 4 Datensatztabelle A, 1 Datensatz in Tabelle B, ...).

Mein Gedanke ist, Abfangpunkte "TransactionStarting", "TransactionStarted", "StatementExecuting", "StatementExecuted", ... zu definieren und ein Kontextobjekt an jeden Punkt zu übergeben.

Dann kann das Projekt eine Klasse "EnteredDateManager" definieren, die das aktuelle Datum während des "TransactionStarted" -Punkts speichert und die EnteredDate-Eigenschaft jedes Objekts während des "StatementExecuting" -Punkts aktualisiert.

Ich möchte dies in der Datei web/app.config einrichten und ermöglichen die Registrierung mehrerer Interception-Klassen. Wenn mehrere Klassen registriert sind, sollten sie in der Reihenfolge ausgelöst werden, in der sie registriert wurden.

Ich dachte daran, nur Ereignisse zu erzeugen, aber ich will, dass Ordnung wichtig ist. Ich möchte auch in der Lage sein, den Zustand zwischen den verschiedenen Punkten zu teilen. In meinem obigen Beispiel wird die EnteredDate-Eigenschaft im TransactionStarted-Punkt festgelegt und im StatementExecuting-Punkt verwendet.

Ist dies das Muster der Verantwortungskette? AOP? Es scheint nahe zu sein, wie die ASP.Net-Pipeline funktioniert, aber sie verwenden Ereignisse und garantieren nicht, soweit ich weiß.

Jede Richtung/Beispiele wäre großartig.

Dank

Antwort

0

Eine Möglichkeit, dies zu tun, ist die grundlegende Strategie-Muster nur zu verwenden. Mit der Strategie schieben Sie die Funktionalität grundsätzlich in eine separate Klasse, die von Ihrer Klasse aufgerufen wird, anstatt die Logik direkt in der ursprünglichen Klasse zu implementieren. Die Strategieklassen können in die ursprüngliche Klasse eingefügt werden, indem sie über schnittstellenbasierte Eigenschaften oder über Konstruktorargumente (oder beides) festgelegt werden. Auf diese Weise kann der Benutzer verschiedene Arten von Funktionen in einen von der ursprünglichen Klasse definierten Verarbeitungsablauf einfügen.

0

Wenn dies .NET-spezifisch ist (Sie erwähnten ASP.NET), empfehle ich dringend, in den System.Transactions-Namespace zu schauen und etwas über das Erstellen und Registrieren von Ressourcenmanagern in einer Transaktion zu lesen.

Mit TransactionScope können Sie eine Transaktion im Kontext erstellen, und der Ressourcenmanager, der in diesem Kontext ausgeführt wird, kann das Vorhandensein einer Transaktion erkennen und sich registrieren (dies wäre gleichbedeutend mit Ihrem TransactionStart-Ereignis). Nach der Registrierung hat jeder Ressourcenmanager die Möglichkeit, seine Änderungen entweder zu bestätigen oder ein Rollback der Transaktion durchzuführen.

Der Namespace "System.Transactions", der mit .NET 2.0 eingeführt wurde, bietet einige sehr nützliche Tools zum Erstellen von Transaktionen und zum Verwalten von Transaktionsressourcen.Sie haben die Möglichkeit, sowohl leichte Transaktionen als auch komplexere, vollständig verteilte Transaktionen durchzuführen, die vom MSDTC-Dienst verwaltet werden. Transaktionen können einphasige Festschreibung oder zweiphasige Festschreibung sein und bieten eine große Flexibilität und Stabilität angesichts von Transaktionsfehlern.

1

Klingt wie Aspect-Oriented Programmierung für mich. Schauen Sie sich PostSharp an.

Hier ist ein Beispiel von ihrer Website des Aufspürens:

public class TraceAttribute : OnMethodBoundaryAspect 
{ 
    public override void OnEntry(MethodExecutionEventArgs eventArgs) 
    { Trace.TraceInformation("Entering {0}.", eventArgs.Method); } 

    public override void OnExit(MethodExecutionEventArgs eventArgs) 
    { Trace.TraceInformation("Leaving {0}.", eventArgs.Method); } 
} 

ich es Protokollierung zu tun verwenden/Tracing, Caching und Performance-Monitoring.

Verwandte Themen