Was machen Interzeptoren wirklich mit meiner c # Klasse?

7

Ich wurde gebeten, Castle Dynamic Proxy in meiner asp.net Webanwendung zu implementieren und ich ging durch ein paar Artikel, die ich von Castle Project und Code Project über den dynamischen Proxy von Castle in der ASP-Webanwendung ....

Beide Artikel befassen sich mit dem Erstellen von Interzeptoren, aber ich kann nicht verstehen, warum Interzeptoren mit Klassen verwendet werden .... Warum sollte ich meine Klasse abfangen, die sich richtig verhält?

    
Chendur Pandian 07.04.2010, 13:31
quelle

2 Antworten

44

Nehmen wir an, Ihre Klasse muss für eine bestimmte Operation drei Dinge tun:

  1. Führen Sie eine Sicherheitsprüfung durch;
  2. Protokollieren Sie den Methodenaufruf;
  3. Cache das Ergebnis.

Nehmen wir weiterhin an, dass Ihre Klasse nichts über die spezifische Art weiß, wie Sie Ihre Sicherheit, Protokollierung oder Zwischenspeicherung konfiguriert haben. Sie müssen auf Abstraktionen dieser Dinge angewiesen sein.

Es gibt ein paar Möglichkeiten. Eine Möglichkeit wäre, eine Reihe von Schnittstellen einzurichten und die Konstruktorinjektion zu verwenden:

%Vor%

Das ist kein schrecklicher Code, aber denken Sie an die Probleme, die wir einführen:

  • Die Klasse OrderService kann nicht ohne alle drei Abhängigkeiten funktionieren. Wenn wir es so machen wollen, müssen wir anfangen, den Code überall mit Null-Checks zu füllen.

  • Wir schreiben eine Tonne zusätzlichen Code, um eine relativ einfache Operation auszuführen (eine Order nachschlagen).

  • Dieser Code muss in jeder -Methode wiederholt werden, was zu einer sehr großen, hässlichen, fehleranfälligen Implementierung führt.

Hier ist eine Klasse, die viel einfacher zu pflegen ist:

%Vor%

In Aspektorientierte Programmierung werden diese Attribute Punkte beitreten , wobei der komplette Satz als Punkteschnitt bezeichnet wird.

Anstatt den Abhängigkeitscode tatsächlich immer und immer wieder zu schreiben, hinterlassen wir "Hinweise", dass einige zusätzliche Operationen für diese Methode ausgeführt werden sollen.

Natürlich müssen diese Attribute irgendwann in Code umgewandelt werden , aber Sie können dies bis zu Ihrem Hauptanwendungscode verschieben, indem Sie einen proxy erstellen OrderService (Beachten Sie, dass die GetOrder -Methode zu virtual gemacht wurde, weil sie für den Service überschrieben werden muss), und zum Abfangen der GetOrder -Methode.

Das Schreiben des Interceptors könnte so einfach sein:

%Vor%

Und das Erstellen des Proxy wäre:

%Vor%

Dies ist nicht nur viel weniger repetitiven Code, aber es entfernt vollständig die tatsächliche Abhängigkeit , weil schauen, was wir getan haben - wir haben nicht ein Autorisierung oder Caching-System noch, aber das System läuft noch. Wir können die Berechtigungs- und Caching-Logik später einfach einfügen, indem wir einen anderen Interceptor registrieren und nach AuthorizeAttribute oder CacheAttribute suchen.

Hoffentlich erklärt das das "warum".

Sidebar: Wie Krzysztof Koźmic bemerkt, ist es kein "Best Practice" der DP, einen dynamischen Interceptor wie diesen zu verwenden. Im Produktionscode möchten Sie nicht, dass der Interceptor nach unnötigen Methoden läuft. Verwenden Sie daher ein IInterceptorSelector statt.

    
Aaronaught 07.04.2010, 14:05
quelle
2

Der Grund, warum Sie Castle-DynamicProxy verwenden würden, ist die sogenannte aspektorientierte Programmierung. Sie können Code in den Standard-Operationsablauf Ihres Codes einfügen, ohne vom Code selbst abhängig zu sein.

Ein einfaches Beispiel ist wie immer das Protokollieren. Dass Sie einen DynamicProxy um eine Klasse erstellen würden, bei der Sie Fehler haben, dass sie die in die Methode eingehenden Daten protokolliert, alle Ausnahmen abfängt und dann die Ausnahme protokolliert.

Mit dem Intercepter hat Ihr aktueller Code keine Ahnung, dass er existiert (vorausgesetzt, Sie haben Ihre Software entkoppelt mit Interfaces korrekt erstellt) und Sie können die Registrierung Ihrer Klassen mit einer Inversion des Control Containers ändern, um stattdessen die Proxy-Klasse zu verwenden ohne eine einzige Zeile ändern zu müssen wo sonst im Code. Dann, wenn Sie den Fehler beheben, können Sie die Vertretung deaktivieren.

In NHibernate ist eine erweiterte Verwendung der Proxyfunktion zu sehen, bei der das gesamte verzögerte Laden über Proxies erfolgt.

    
Chris Marisic 07.04.2010 13:43
quelle