2016-03-25 22 views
2

Ich fand this question - das ist sehr ähnlich zu dem, was ich versuche. Mein Anwendungsfall ist jedoch etwas anders.Kann ein C# -Attribut einen Parameter zu einer Methode hinzufügen?

Wir müssen Audit-Historie für Business-Services speichern. Allerdings müssen wir Audit-Checkpoints während des Methodenaufrufs manuell aufrufen können, nicht nur davor und danach.

Wir verwenden Castle.Core in unserem Projekt. Um dies zu erreichen, plane ich, ein benutzerdefiniertes Attribut mit dem Namen AuditContext zur Verwendung auf unseren Service-Methoden zu erstellen (um Geschäftslogik zu prüfen, etc.). Ich plane, Castle DynamicProxy zu verwenden, um einen Logging-Proxy zu erstellen, der ein neues Kontextobjekt basierend auf den Metadaten erstellt Argumente im Attributobjekt. Ich möchte dieses Objekt als Methodenargument in meine Methode einfügen, ohne jedoch einen AuditContext Parameter für jede von uns erstellte Dienstmethode angeben zu müssen.

Im Wesentlichen statt dessen:

[AuditContext(someStaticMetadata) 
public BusinessObject BusinessMethod (AuditContext context, ...arguments) { 
    // ...some logic... 
    context.checkpoint(someAuditData); 
} 

Ich möchte, dies zu tun in der Lage:

[AuditContext(someStaticMetadata) 
public BusinessObject BusinessMethod (...arguments) { // We do not have to specify the context object for every business method... 
    // ...some logic... 
    context.checkpoint(someAuditData); // ...but the object is still available, as the parameter has been added by the argument. 
} 

Oder ein viel allgemeineres Beispiel zu machen, möchte ich dies schreiben:

[ProvidesParam2] 
public Object myFunc (param1) { } 

... und mit einer Funktion mit dieser Signatur am Ende:

Die destillierte Frage ist dies - Kann ein C# -Attribut einen Parameter zu einer Methode hinzufügen, die es schmückt und die Signatur der Methode zur Entwurfszeit effektiv ändert?

Danke!

+0

Der einzige Unterschied zwischen dem, was Sie fragen, und der Antwort auf die Frage, die Sie verknüpften, ist, dass der 'AuditContext' einige statische Metadaten benötigt, während die Antwort in der verknüpften Frage eine Schnittstelle benötigt. In jedem Fall müssen Sie die Reflexion verwenden, um ein Objekt zu instanziieren. Wenn Sie mir nicht erklären können, dass das, was Sie fragen, sich von der verknüpften Frage unterscheidet, bin ich geneigt, zu wählen, um als Duplikat zu schließen. –

+0

@JimMischel Der Hauptunterschied zwischen dem, was er macht, und dem, was ich mache, ist, dass ich versuche, ein Attribut zu verwenden, um die Methodensignatur einer Methode zu ändern. Tatsächlich habe ich nur diese Frage gestellt, um zu zeigen, dass es kein Duplikat ist. Mein Anwendungsfall hängt mit seinem zusammen, aber das grundlegende Problem ist anders. Siehe die von mir bereitgestellten Codebeispiele. –

+0

Die einzige Methode, mit der Sie 'someAuditData' erhalten, ohne sie als Parameter übergeben zu müssen, besteht darin, das Attribut' AuditContext' mithilfe von reflection zu suchen und anschließend 'Activator.CreateInstance' zu ​​instanziieren, genau wie die Antwort auf die verknüpfte Frage sagt. Sie können nicht einfach darauf zugreifen, als wäre es ein Parameter. –

Antwort

2

Kurze Antwort: Nein. Attribute modifizieren tatsächlich, was Sie in besonderen Fällen als Signatur interpretieren könnten (wie die Aufrufkonvention), aber sie können die Argumentliste definitiv nicht ändern. Sie können mit einem benutzerdefinierten IL-Rewriter erreichen, was Sie wollen; etwas wie könnte helfen können (Disclaimer: Ich habe überhaupt keine Erfahrung mit PostSharp).