2013-07-23 15 views
5

Ich spiele seit Jahren mit AOP zusammen, bin aber mit den Lösungen nicht zu 100% zufrieden. AOP-Frameworks mit Laufzeitweben, wie Spring.AOP, können die Schnittstelle einer Klasse nicht ändern. Mit der Post-Kompilierzeit Frameworks wie Postsharp (jemand weiß jemand anderes?) Können Sie. Überprüfen Sie dieses Beispiel, es fügt Ihrer Klasse eine INotifyPropertyChanged-Implementierung hinzu. ->http://www.postsharp.net/model/inotifypropertychangedAOP Vorkompilieren Weben?

Das AOP-Funktion ist wirklich toll, aber Sie laufen in Schwierigkeiten sehr bald ... Wenn Sie die neue Schnittstelle in der Hosting-Baugruppe zugreifen möchten, können Sie nicht kompilieren, , da die Schnittstelle nach der Kompilierung hinzugefügt wird . so erhalten Sie einen "PropertyChanged ist nicht definiert" -Fehler. Sie müssen also hässlich umgehen, indem Sie die Klassen in eine andere Baugruppe trennen, damit Sie diese AOP-Vorteile nutzen können. Ich erinnere mich, dass ich in die gleiche "Post Compile Time" -Trouble mit einem T4-Template lief, das Quellcode generiert, basierend auf den reflektierten Informationen einer Assembly. OK, damit die Kompilierzeit manchmal zu spät ist ...

Was ich suche, ist eine Lösung, wo der Quellcode der Klasse über ein visuelles Studio-benutzerdefiniertes Werkzeug geparst wird, und dann erzeugt der Code in einer C# Datei, in einer partiellen Klasse. (also alle AOP angewandten Klassen müssen teilweise sein)

Also seine Art von "Pre-Compile-Time AOP". Dies sollte definitiv möglich sein, und könnte über die Verwendung von NRefactory als Code Parser getan werden. Darüber hinaus möchte Visual Studio viel mehr, als eine nachträgliche Kompilierung.

Diese Lösung beseitigt also die Nachteile der Weber nach dem Kompilieren. aber nicht alle Funktionen von AOP. Aber zusammen mit einem AOP-Framework sollte das großartig sein.

Kennt jemand ein Framework wie dieses oder eine Diskussion?! was denkst du?

freundlichen Grüßen Thomas

Antwort

0

Im Falle von Postsharp, können Sie eine Schnittstelle eingeführt Zugriff auf post-Kompilierung-unter Verwendung des Verfahrens Post.Cast, die eine Art von Cast-Operator ist, die an post-Kompilierung wird überprüft -Zeit. Informationen zur Dokumentation finden Sie unter http://doc.postsharp.net/postsharp-3.0/Content.aspx/PostSharp-3.0.chm/html/M_PostSharp_Post_Cast__2.htm.

+0

danke, IMHO das ist eine Auswirkung auf die Architektur, weil Sie Komplexität (= eine Besetzung) zu Ihrem Code hinzufügen. Ist das einer der Punkte, die Sie Anders Hejlsberg für "Öffnen des Compilers?" Zitat: "Leute von Code Contracts würden wahrscheinlich die Fähigkeit schätzen, den Compiler zu haken. Dieser Bedarf wird weitgehend ignoriert." Quelle: http://www.postsharp.net/blog/post/Anders-Hejlsberg-Dead-Body –

1

Da Sie und ich bereits auf die Verwendung SNAP als eine praktikable Alternative entsprechen, dachte ich, ich würde hier eine Zusammenfassung unserer Diskussion für diejenigen, die nach einer ähnlichen Lösung suchen.

Kurz gesagt, SNAP bietet ein Laufzeit-AOP-Framework, das Ihren Code in keiner Weise ändert. Es gibt keinen Post-Compile-Schritt, nur eine Laufzeitüberwachung, die vorhersehbar und einfach zu verwenden ist.

+0

danke, ich denke, beide Optionen, statische Weben und Runtime DI sind großartige Werkzeuge. Persönlich mag ich statische Weben mehr, weil es weniger Architekturwirkung hat. Natürlich haben Sie mit DI mehr Kontrolle über Ihre Aspekte. aber herzlichen Glückwunsch zu SNAp, du hast ein tolles Projekt gemacht :) –

1

Was Sie suchen, ist pMixins. Es ist immer noch in der Beta, aber es tut genau das, wonach Sie suchen: Design-Time Weben. AOP-Code wird in einer partiellen CodeBehind-Klasse generiert, sodass sie zur Entwurfszeit verfügbar ist.

Also das bedeutet, dass Sie diese in einer Datei tun können, und der Compiler ist glücklich, Visual Studio ist glücklich, ReSharper ist glücklich:

eine Schnittstelle definieren:

public interface ISomeInterface 
{ 
    void SomeMethod(); 
} 

eine Implementierung der Schnittstelle erstellen (ich nenne dies eine Mixin):

public class SomeInterfaceImplementation : ISomeInterface 
{ 
    public void SomeMethod() 
    { 
     //implementation 
    } 
} 

definieren Sie eine Zieldatei (die die Mixin verbrauchen):

[pMixin(Mixin = typeof(SomeInterfaceImplementation))] 
public partial class Target { } 

Lassen Sie uns ein Utility-Klasse erstellen, die mit SomeInterface arbeitet und SomeInterfaceImplementation:

public class Utility 
{ 
    public void DoSomeWorkOnSomeInterface(ISomeInterface obj) 
    { 
     obj.SomeMethod(); 
    } 

    public void DoSomeWorkOnImplementation(SomeInterfaceImplementation obj) 
    { 
     obj.SomeMethod(); 
    } 
} 

Und jetzt machen wir es alle zusammen arbeiten sehen:

class Program 
{ 
    private static void Main(string[] args) 
    { 
     //Call the mixed in method 
     new Target().SomeMethod(); 

     //Target implements ISomeInterface is code-behind 
     new Utility().DoSomeWorkOnSomeInterface(new Target()); 

     //Target has an implicit conversion operator to 
     //SomeInterfaceImplementation in code-behind 
     new Utility().DoSomeWorkOnImplementation(new Target()); 
    } 
} 

Der Grund dies funktioniert, ist, weil, sobald Sie Speichern Sie die Datei, der pMixins-Code-Generator macht sofort Design-Weben und aktualisiert die Code-Behind-Datei. Es fügt die SomeMethod direkt zu Target hinzu, aktualisiert Target 's Klassendefinition, um ISomeInterface zu implementieren, und erstellt Umwandlungsoperatoren.

Offenlegung: Ich bin auf dem pMixins-Entwicklungsteam.

+0

BTW @ Gael-Fraiteur - PostSharp ist ein großartiges Werkzeug und hat mich in C# auf AOP gebracht! –

+0

@Thomas Haller - Sie sind genau richtig mit Ihrem Vorschlag, dass es mit NRefactory gemacht werden könnte. Genau das habe ich benutzt! –