Is there a way in C# or .NET in general to create an attribute on a method which triggers an event when the 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.
Best Solution
This concept is used in MVC web applications.
The .NET Framework 4.x provides several attributes which trigger actions, e.g.:
ExceptionFilterAttribute
(handling exceptions),AuthorizeAttribute
(handling authorization). Both are defined inSystem.Web.Http.Filters
.You could for instance define your own authorization attribute as follows:
Then, in your controller class you decorate the methods which are supposed to use your authorization as follows:
Whenever the
Post
method is invoked, it will call theIsAuthorized
method inside themyAuthorization
Attribute before the code inside thePost
method is executed.If you return
false
in theIsAuthorized
method, you signal that authorization is not granted and the execution of the methodPost
aborts.To understand how this works, let's look into a different example: The
ExceptionFilter
, which allows filtering exceptions by using attributes, the usage is similar as shown above for theAuthorizeAttribute
(you can find a more detailed description about its usage here).To use it, derive the
DivideByZeroExceptionFilter
class from theExceptionFilterAttribute
as shown here, and override the methodOnException
:Then use the following demo code to trigger it:
Now that we know how it is used, we're mainly interested in the implementation. The following code is from the .NET Framework. It uses the interface
IExceptionFilter
internally as a contract:The
ExceptionFilterAttribute
itself is defined as follows:Inside
ExecuteExceptionFilterAsync
, the methodOnException
is called. Because you have overridden it as shown earlier, the error can now be handled by your own code.There is also a commercial product available as mentioned in OwenP's answer, PostSharp, which allows you to do that easily. Here is an example how you can do that with PostSharp. Note that there is an Express edition available which you can use for free even for commercial projects.
PostSharp Example (see the link above for full description):
Here the attribute specifies that the
Save
method is called up to 5 times if an exception occurs. The following code defines this custom attribute: