Posts tagged with 'c'
Recently I was made aware of another AOP tool for .NET that uses a post-compile step to do the weaving (similar to PostSharp). SheepAspect appears to use the Mono.Cecil library, which is a powerful utility to work with CIL assemblies. I mentioned SheepAspect in an earlier post, and I thought it deserved a closer look.
SheepAspect is available via NuGet, so it's an easy install. Here's a 'Hello, World' aspect in a console app that I threw together:
It's a somewhat unfamiliar approach to me, being used to PostSharp.
- To define an aspect, create a class and put the [Aspect] attribute on it. So far so good.
- You don't use attributes to apply the aspect to your code. Notice that MyClass and DoStuff are not decorated with any attributes.
- Instead, you define a pointcut by creating an empty "marker" method (MyPointcut in the above example), and placing a selector attribute on that. The one I'm using is SelectMethods, but there are others available.
- The string in that SelectMethods attribute is called SheepAop Query Language (SAQL).
- The advice goes into the InterceptMethod method, which returns an object and gets an MethodJointPoint (yes MethodJointPoint, not MethodJoinPoint, that's not a typo). MethodJointPoint is very similar to DynamicProxy's IIntercept or PostSharp's MethodInterceptionArgs, in that it gives you a context to work with.
- I put an "Around" attribute on this method to specify that I want this advice to surround the pointcut, and I specified the pointcut with the string.
Compile and run, and here's the output:
After using SheepAspect in this admittedly trivial way, I do think it has some potential, but it also feels like a project that's in its very early stages and is a little rough around the edges still.
- SAQL is a very interesting way to select pointcuts, and based on the SAQL documentation that I've read, it can be very powerful. This is a double-edged sword though: this query language is specific to SheepAspect, so you'll have to spend some time learning it to get the most use out of it.
- SAQL queries are just strings, so refactoring/renaming could be problematic. Perhaps if you are coming from an AspectJ environment, this would not be as difficult, since that's what SheepAspect seems to modeled on. A Linq provider would be tremendous, but that might be very ambitious, if not impossible.
- The fact that SheepAspects are only connected to your regular code by SAQL is also an interesting approach: your pre-compile source code goes completely untouched, which is nice and clean, but it could also be hard to keep track of what aspects are being applied where.
- Finally, while there is some good documentation, it looks like some of it has yet to be written, which indicates to me that it's still very much a work in progress.
I can't say I'd recommend using SheepAspect over more mature and supported tools like PostSharp or Castle DynamicProxy, but it might be worth a look for specialized usage in low risk situations. In the future, who knows; it could develop into a very popular tool.
I'm trying to cut through some of the confusion around AOP by providing simple definitions and examples of often obtuse terminology (see also: other terminology posts).
Today's term: pointcut.
A pointcut is a simply a set (or an expression that returns a set) of join points. If a join point is a single line between two boxes on a flowchart, then a pointcut would be a description of a set of those lines.
For instance, if you wanted to put some logging after every time a method in a given class was called, you'd first get a pointcut of all the join points that occur after each method. If there are 5 methods in your class, you have 5 join points that make up the specified pointcut.
So if your aspect defines "OnExit", and you apply that aspect to a class "CustomerRepository", then your pointcut is "whenever a method in CustomerRepository exits". You could narrow that to a single method, or expand it to an entire namespace.
As an exercise, let's examine this snippet of code:
obj1.Method1(); // obj1 is of type Class1 obj1.Method2(); obj2.MethodA(); // obj2 is of type Class2
And now a flow chart of that, identifying exit join points:
So which of those join points would be included in a pointcut of "exiting a method of Class1"? Answer:
Building on the overview of ActionFilters in MVC, I'm going to go into a deeper dive on the various overrides that you can use inside of an ActionFilter, starting with OnActionExecuting.
OnActionExecuting is run before the Action is executed. You can put whatever code you want in here, including something as simple as just writing some raw HTML out before the Action is executed. But the real power comes from the filterContext parameter (of type ActionExecutingContext) that gets passed in to your OnActionExecuting method. This object gives you a whole bunch of information about the current context of the action that you are filtering. You can use this information to control logic or, conversely, you can manipulate the context according to your logic.
I wrote a "kitchen sink" filter combined with a Razor view to give you an idea of what kind of context you can view and/or manipulate.
All this does is expose the filterContext object to the view, where I can display some of the information available.
Here's a screenshot of the output. Note the URL (/Home/Index/parameter_value_here?anotherParam=99) as you look through the screenshot.
I've broken this output into 4 sections of different context information you can get. The first 4 are ASP.NET MVC specific: Controller, Action, Action Result, and Route. The last one, Http Context, is more general to ASP.NET.
Controller
You can get the controller name, the controller type, and even the controller instance, depending on your need. You can try to cast the controller to a specific controller if you want and access properties of that controller (I wouldn't recommend that generally, but you'll note that's how I did my kitchen sink action filter, by casting to the HomeController type).
Once you have a controller instance, you can access ViewBag, ViewData, TempData, all of which allows you to communicate to the action (and ultimately the view) if you choose to.
You can also access custom attributes here, which opens up some possibilities in declarative programming and use of metadata.
Action
You can again, get the name (of the action this time) if you want just that. You can also get some reflection information about the parameters. If you look at ActionParameters, you can get the parameter names along with the arguments. And once again, you can access custom attributes here, just as you can with controllers.
Action Result
You have the ability to get the ActionResult that the Action will return. At this point in the life cycle, that ActionResult is probably null, so I'm not exactly sure what you would want to do with it. But it's there. You could create a RedirectResult and immediately execute it; I suppose that might come in handy.
Route
I generally would not recommend messing around with routes in your action filters, as things could get really confusing in ASP.NET MVC, but you have access to RouteData, Values and DataTokens here too.
Http Context
Finally, Http Context, which contains just about everything you need to work with your standard Http objects like Response, Request, Session, etc. Do note that the objects you get are generally base classes (e.g. HttpResponseBase and HttpRequestBase), so you may not have access to some of the methods and properties that you are used to.
With the Http Context available, you can do some interesting things like checking to see if the session expired, and then either reloading the session from a db or cookie or something, or redirecting to a 'timeout' or other message page.
There's more?
This isn't even an exhaustive list of the stuff you can get to via the ActionExecutingContext being passed in. I've just tried to list some of the more useful properties and examples of data that could be in those properties and left out the esoteric stuff. But there's a lot of power here to do almost anything you want before an action starts executing.
You're going to see very similar properties in the other action filter override context objects, but there are some differences that I'll explore in later posts.
I've been doing some research on Castle DynamicProxy for an upcoming screencast that I'm working on. So far, it's a pretty simple tool to use, and feels very familiar to other AOP tools that I've used. Here's a 101-level example:
And here's the output of that example:
Not particularly elegant, but by using an IoC container you can make it much cleaner and transparent (which will also be part of the screencast).
This is the first "Weekly Concerns" (thank you Jason Karns for the name) post, of what is going to be a weekly series of blog posts that's basically just a Friday link dump. Not that each of these links don't deserve more attention and research, but, hey, I get lazy sometimes, alright!
- SharpCrafters webinar - "How to Stay DRY with AOP and PostSharp", featuring PostSharp developer Igal Tabachnik
- White paper from Cornell about using AOP in seperating concerns (available in PDF and other formats)
- The NDC conference in 2011 had an "AOP & IoC" track. I'm guessing many of you didn't make it to Norway for this conference (I didn't), but the NDC is kind enough to make video of the sessions available. Day 3, Track 5 features Gael Fraiteur (creator of PostSharp), Donald Belcham (fellow PostSharp MVP), and some other sessions about the more general topic of rewriting IL.
- SheepAspect for .NET - another AOP framework that uses IL rewriting. I've not heard of this one much, but it is open source and probably deserves a closer look (perhaps in a future blog post).
- AOP for Perl (yes, Perl!) with Aspect from Adam Kennedy (who has his own Wikipedia page), with a very comprehensive and well written README that's a pretty good primer on AOP in general.