2009-08-29 13 views
6

Chciałbym móc ozdobić dowolną metodę niestandardowym atrybutem Trace, a część kodu powinna zostać wprowadzona do tej metody podczas kompilacji.Jak wstrzyknąć kod C# podczas kompilacji?

Na przykład:

[Trace] 
public void TracedMethod(string param1) 
{ 
    //method body 
} 

powinny stać się:

public void TracedMethod(string param1) 
{ 
    Log.Trace("TracedMethod", "param1", param1); 
    //method body 
} 

W tym przypadku, wstrzykuje kod zależy od nazwy metody i sposób parametrami, więc powinno być możliwe, aby wywnioskować tę informację.

Czy ktoś wie, jak to osiągnąć?

Odpowiedz

13

Aby wykonać programowanie zorientowane na aspekt w języku C#, można użyć PostSharp.

(The homepage nawet pokazuje Trace przykład, podobnie jak prosisz!)

+0

Nigdy nie badałem wydajności kodu PostSharpened, ale byłbym zaskoczony, gdyby podkładka PostSharp zrobiła znaczącą różnicę. – RichieHindle

+0

Nie mogę zrobić tego, co chcę zrobić z PostSharp Loas (wtyczka AOP dla PostSharp), ale mogę to zrobić, pisząc niestandardową wtyczkę AOP dla PostSharp. Chociaż PostSharp Loas mógł wpłynąć na wydajność w czasie wykonywania, moja niestandardowa wtyczka nie będzie, ponieważ będzie to tylko czas kompilacji. –

2

Można to łatwo zrobić z systemem transformacji programu.

DMS Software Reengineering Toolkit jest uniwersalnym programem do transformacji programów i może być używany z wieloma językami (C++, COBOL, Java, EcmaScript, Fortran, ...), a zwłaszcza z C#.

DMS analizuje kod źródłowy, kompiluje abstrakcyjne drzewka składni i umożliwia stosowanie wzorów źródłowych do kodu źródłowego w celu przekształcenia kodu z jednego programu C# do innego z dowolnymi właściwościami. Zasadą transformacji do osiągnięcia dokładnie zadanie określono byłoby:

domain CSharp. 

insert_trace():method->method 
    "[Trace] 
    \visibility \returntype \methodname(string \parametername) 
    { \body } " 
     -> 
    "\visibility \returntype \methodname(string \parametername) 
    { Log.Trace(\CSharpString\(\methodname\), 
       \CSharpString\(\parametername\), 
       \parametername); 
     \body } " 

Znaki cudzysłów (") nie są znakami CSharp cytat, ale raczej są«cytaty domena»i wskazują, że zawartość wewnątrz cudzysłowów jest składnia CSharp (bo powiedział: „CSharp domeny”). zapisy \ Foo są składnia meta.

zasada ta odpowiada AST reprezentujący metodę określoną z przycisk [nazwiska] adnotacji i przepisuje że AST na Wynikowy AST jest następnie odręczny z powrotem do formy źródłowej, którą możesz skompilować. Prawdopodobnie potrzebujesz innych reguł do obsługi innych kombinacji argumentów; działa, prawdopodobnie uogólnisz przetwarzanie argumentów, aby wytworzyć (jeśli jest to praktyczne) wartość ciągu dla każdego argumentu skalarnego.

Powinno być jasne, że można zrobić o wiele więcej niż tylko rejestrowanie za pomocą tego i znacznie więcej niż tylko programowanie zorientowane na aspekt, ponieważ można wyrażać dowolne transformacje, a nie tylko działania poprzedzające.

+0

Chociaż brzmi to bardzo przydatny, mam zamiar spróbować PostSharp pierwszy, ponieważ jest bezpłatny i dostęp do źródła. Byłbym też w stanie zmienić nazwy atrybutów w dowolnym momencie i niczego nie złamać. –

+0

Dlaczego sprzeciwiasz się z powodu zmiany nazwy atrybutu? Jeśli chcesz zmienić nazwy atrybutów, możesz również napisać transformację programu, aby to zrobić. –

Powiązane problemy