tags:

views:

244

answers:

2

Basically I'm trying to implement some sort of poor man's Aspect Oriented Programming in C#. I had thought about using a ContextAttribute but they seem only be be bound at the class level. Is there any way that I can put an attribute in such that it will receive the same parameters as the method which it annotates or some way to access the context in which it fired?

I have this code

public void AddUser(User user)
{
    var errors = DataAnnotationsValidationRunner.GetErrors(user);
    if (errors.Any())
           throw new RulesException(errors);
    users.Add(user);
}

from which I would like to extract the first 3 lines so I had something like

[Validated]
public void AddUser(User user)
{
   users.Add(user);
}
+1  A: 

Don't know exactly how your solution should look like, but in C# attributes do not execute code as long as you don't request them (as far as I know). And if you query for the attribute, you also have the context. So there is something wrong with your strategy in my opinion.

Achim
+2  A: 

I think you are missing a third component. Most AOP implementations (e.g. Aspect#) rely on a proxy or interceptor to actually execute the code. In your scenario, you lack whichever component needed to 1) know the attribute exists on the method, and 2) trigger the mechanism (or become it) needed to execute the code within the attribute.

Fortunately, there are already many (fairly) simple solutions available in open source. The simplest option I can think of would be to use a compile-time weaver like PostSharp. Grab a copy of that, and in the samples you'll find several examples of exactly what you are trying to do (you'd be interested in the OnMethodInvocationAspect).

The end result is that your code looks exactly like it does in the sample you provided, yet it's also running the code you wish.

joshua.ewer
+1 for PostSharp
Chris McCall
This is perfect, I didn't realize that there was an aspect weaver for C# having read somewhere that it wasn't possible. I guess postsharp comes out of http://zombo.com where the impossible is possible.
stimms
Just FYI, take a look at the plugins that come with Postsharp. I know that log4postsharp (which marries log4net and postsharp) comes w/ as Log[] attribute that will log entry/exit into a method (including reflecting over all the parameters passed in (and their values!)). You could just rewrite that code to do whatever validation you'd like. It would definitely save you some time...
joshua.ewer