views:

344

answers:

2

Hello, all. Maybe i've not googled enough, but i can't find any example on this question.

It is possible in C# to create an custom attribute which, applied to a class, modifies all of its methods? For example, adds Console.WriteLine("Hello, i'm modified method"); as a first line (or it's IL equivalent if it's done at runtime)?

+4  A: 

No. What you are looking for is aspect oriented programming (AOP).

With AOP you specify a pointcut, a place where you want to weave in code, and the code you want to executed at that point. Tracing is the standard example for AOP. You specify a set of methods and the the weaver/compiler to add you log/tracing call at the beginning or the end of that methods.

EricSchaefer
PostSharp - Bringing AOP to .NET (http://www.postsharp.org/)
Yossarian
There are more .NET-AOP Extensions at the end of the linked wikipedia page (footnote 6)
EricSchaefer
Definitely AOP technique.
Juri
+3  A: 

Yes, you can do this, but no, its not built in to C#. As Eric says, this technique is known as Aspect Oriented Programming.

I've used PostSharp at work, and it is very effective. It works at compile time, and uses IL-weaving, as opposed to other AOP techniques.

For example, the following attribute will do what you want:

[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method | MulticastTargets.Class,
                         AllowMultiple = true,
                         TargetMemberAttributes = MulticastAttributes.Public | 
                                                  MulticastAttributes.NonAbstract | 
                                                  MulticastAttributes.Managed)]
class MyAspect : OnMethodInvocationAspect
{
    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
    {
        Console.WriteLine("Hello, i'm modified method");

        base.OnInvocation(eventArgs);
    }
}

You simply apply MyAspect as an attribute on your class, and it will be applied to every method within it. You can control how the aspect is applied by modifying the TargetmemberAttributes property of the MulticastAttributeUsage property. In this example, I want to restrict it to apply only to public, non-abstract methods.

There's a lot more you can do so have a look (at AOP in general).

Nader Shirazie
Thx for example, that's what i needed. How i understand, such technique gives no perfomance loss at runtime?
ALOR
The best way to satisfy your performance concerns is to measure the performance and see if it is good enough. However, a simple thing to do is to just open up the resulting assembly in reflector (http://www.red-gate.com/products/reflector/) and look at the resulting code. See what you think. We haven't seen any problematic performance issues from using this technique at work.
Nader Shirazie