views:

2586

answers:

6

Is there a way in C# or .NET in general to create an attribute on a method which triggers an event when a method is invoked? Ideally, I would be able to run custom actions before and after the invocation of the method.

I mean something like this:

[TriggersMyCustomAction()]
public void DoSomeStuff()
{
}

I am totally clueless how to do it or if it possible at all, but System.Diagnostic.ConditionalAttribute might do a similar thing in the background. I am not sure though.

EDIT: I forgot to mention that due to the circumstances of my specific case, performance is not really an issue.

+7  A: 

The only way I know how to do this is with PostSharp. It post-processes your IL and can do things like what you asked for.

OwenP
I voted up this answer because it's my thought as well: you're gonna need some tool to run after the build to analyze your IL, look for methods with your attribute, and inject some event logic.
Judah Himango
I just found out about PostSharp and went hunting for this question to post it as an answer.
cfeduke
+1  A: 

I don't think there is a way to do it with just an attribute, but using proxy classes and reflection you could have a class that knows to intercept instantiations of the classes in which you have attributed methods.

Then the proxy class can trigger an event whenever the attributed methods are called.

SoloBold
A: 

An attribute gives information, they are metadata. I don't know of a way to do this offhand, someone might.

You could look at partial methods in .NET which allow you to do some lightweight event handling. You provide the hooks and let someone else handle the implementation. If the method isn't implemented the compiler just ignores it.

http://msdn.microsoft.com/en-us/library/wa80x488.aspx

Nick
+1  A: 

You will be able to do this using policy injection

Try the EL policy injection application block http://msdn.microsoft.com/en-us/library/cc309507.aspx

NimsDotNet
+2  A: 

You need some sort of Aspect oriented framework. PostSharp will do it, as will Windsor.

Basically, they subclass your object and override this method...

then it becomes:

//proxy
public override void DoSomeStuff()
{
     if(MethodHasTriggerAttribute)
        Trigger();

     _innerClass.DoSomeStuff();
}

of course all this is hidden to you. All you have to do is ask Windsor for the type, and it will do the proxying for you. The attribute becomes a (custom) facility I think in Windsor.

Ben Scheirman
+1  A: 

You can use ContextBoundObject and IMessageSink. See http://msdn.microsoft.com/nb-no/magazine/cc301356(en-us).aspx

Be warned that this approach has a severe performance impact compared with a direct method call.

Hallgrim