2012-03-24 4 views
4

Ich habe das OnMethodBoundaryAspect Attribut in der PostSharp library gegründet. Es kann Eingang und Ausgang von der Methode wie folgt abfangen:Wie funktioniert OnMethodBoundaryAspect?

[Serializable] 
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.Multicast)] 
public class InterceptAttribute : OnMethodBoundaryAspect 
{ 
    public override void OnEntry(MethodExecutionArgs args) 
    { } 

    public override void OnExit(MethodExecutionArgs args) 
    { } 
} 

public class A 
{ 
    [Intercept] 
    public void foo() { } 
} 

Und meine Frage ist "Wie funktioniert es?" Was soll ich tun, um mein eigenes Attribut zu schreiben, das in der Lage ist, den Eintritt und den Ausgang von der Methode (ohne PostSharp mit natürlich) abzufangen?

Antwort

9

Zuerst würde ich empfehlen, folgende documentation für interne Arbeiten zu lesen (die "wie es funktioniert" Abschnitte und andere). Grundsätzlich werden die Attribute zum Build-Zeitpunkt in den relevanten Code übersetzt (eigentlich meist nach dem Build, aber noch während des Aufbaus). Es gibt eine Vorstellung von MSBuild task, die den Code angibt, der während des Erstellungsprozesses ausgeführt werden soll. Der Code wird nach der Kompilierung ausgeführt und sucht nach bestimmten Attributen (wie InterceptAttribute) und kann Änderungen am kompilierten Code vornehmen. Laufzeitänderungen an dem Code können ausgeführt werden, während die Mono.Cecil-Bibliothek verwendet wird (sie ermöglicht das Einfügen/Entfernen von IL-Code). Noch einmal, um zu klären:

  1. Der Code ist mit Attributen zugeordnet.
  2. Beim Build wird spezifischen Code pro BuildTasks genannt
  3. BuildTasks Reflexion Teile des Codes zu finden, verwenden geschrieben, die notwendig enthalten Attribute
  4. BuildTasks Mono.Cecil Code auf jene Stücke
  5. Erstellen gefunden dynamisch zu injizieren verwenden ist Komplett. Ihre kompilierte DLL enthält jetzt nicht nur den geschriebenen Code, sondern auch die Attribute, die in Code geändert wurden. Ich würde vorschlagen, die Assembly mit ILSpy oder ähnlichen Decompilern zu betrachten, um den Unterschied zwischen Ihrem ursprünglichen Code und dem erzeugten zu erkennen.

Ich würde empfehlen, bei KindOfMagic Codes suchen, um zu sehen, wie die automatischen INotifyPropertyChanged des RaisePropertyChanged als Attribut implementiert wird. Es bietet wertvolle Einblicke in die Erstellung von benutzerdefinierten Aspekten, obwohl es sich als schwieriger und langwieriger Prozess erweisen kann.