I recently co-authored an arti­cle with Gael Frai­teur (cre­ator of Post­Sharp) on how AOP frame­works such as Post­Sharp can be used to auto­mate the imple­men­ta­tion of com­mon design pat­terns in .Net.

The arti­cle is now avail­able to view on the InfoQ web­site here. A more offline friendly PDF ver­sion is also avail­able here and from Post­Sharp’s brand new site.

 

Hope you enjoy what we have to say on the topic, and please don’t hes­i­tate to give us your feedbacks!

Share

Whilst search­ing for an ele­gant solu­tion to apply string intern­ing across a large num­ber of classes (we’re talk­ing about hun­dreds of classes here..) it dawned on me that I can achieve this with ease using PostSharp’s Loca­tion­In­ter­cep­tionAspect. All I needed was some­thing along the lines of:

You can apply this attribute to a class or even a whole assem­bly and it’ll ensure every piece of string con­structed is interned, includ­ing string prop­er­ties and fields defined by its sub­class, which is exactly what I was after.

For exam­ple, take this triv­ial piece of code:

image

If you inspect the com­piled code for the Base class in ILSpy you will see some­thing along the lines of:

image

notice how the set­ter for BaseS­tring­Prop­erty has been mod­i­fied to invoke the OnSet­Value method defined in our aspect above as opposed to the set­ter method. In this case, it’ll call the String.Intern method to retrieve a ref­er­ence to an interned instance of the string and set the prop­erty to that reference.

For more details on PostSharp’s inter­cep­tion aspects, I rec­om­mend read­ing Dustin Davis’s excel­lent posts on the topic:

Post­Sharp Prin­ci­ples: Day 7 Inter­cep­tion Aspects – Part 1

Post­Sharp Prin­ci­ples: Day 8 Inter­cep­tion Aspects – Part 2

 

As we’ve spec­i­fied the mul­ti­cast inher­i­tance behav­iour to mul­ti­cast the attribute to mem­bers of the chil­dren of the orig­i­nal ele­ment, the string prop­er­ties defined in both A and B classes are also sub­ject to the same string intern­ing treat­ment with­out us hav­ing to explic­itly apply the Inter­nAt­tribute on them:

image

 

F# Com­pat­i­ble

What’s more, this attribute also works with F# types too, includ­ing record and dis­crim­i­nated unions types. Take for instance:

image

If you look at the gen­er­ated C# code for the dis­crim­i­nated union type, the inter­nal MyDuType.CaseB type would look some­thing like the following:

image

notice how the two inter­nal item1 and item2 properties’s set­ter meth­ods have been mod­i­fied in much the same way as the C# exam­ples above? The pub­lic Item1 and Item2 prop­er­ties are read-only and get their val­ues from the inter­nal prop­er­ties instead.

Indeed, when a new instance of the CaseB type is con­structed, it is the inter­nal prop­er­ties whose val­ues are initialized:

image

 

Finally, let’s look at the record type, which inter­est­ingly also defines a non-string field:

image

because we have spec­i­fied that the Inter­nAt­tribute should only be applied to prop­er­ties or fields of type string (via the Com­pile­TimeVal­i­date method which is exe­cuted as part of the post-compilation weav­ing process as opposed to run­time), so the inter­nal rep­re­sen­ta­tion of the Age field is left unaltered.

The Name field, how­ever, being of string type, was sub­ject to the same trans­for­ma­tion as all our other examples.

 

I hope this lit­tle attribute can prove to be use­ful to you too, it has cer­tainly saved me from an unbear­able amount of grunt work!

Share

NOTE: if you’re unfa­mil­iar with how Post­Sharp works under the hood, I highly rec­om­mend that you check out Dustin Davis’ excel­lent Post­Sharp Prin­ci­ples series of blog posts here.

The Prob­lem

The new async/await key­words in C# are pretty awe­some, and makes life an awful lot eas­ier when writ­ing asyn­chro­nous and non-blocking IO code. How­ever, for those of us who are using frame­works such as Post­Sharp to deal with cross-cutting con­cerns we now face a new chal­lenge – the aspects which we have come to rely upon no longer works the way we expect them to when applied on async meth­ods (which returns void, Task or Task<T>), as can be seen from the exam­ples below:

So what’s wrong here?

If you take a look at the code from the above exam­ple using a decom­piler such as Jet­Brain’s Dot­Peek, you’ll see that the nor­mal syn­chro­nous ver­sion of Foo looks some­thing along the line of:

image

As you can see, the weaved code include calls to the OnEn­try, OnSuc­cess and OnEx­cep­tion meth­ods pro­vided by the OnMethod­Bound­aryAspect class, so every­thing is as expected here.

For FooA­sync how­ever, the pic­ture is a lit­tle more complicated:

image

Turns out the C# com­piler rewrites async meth­ods into a state machine which means that although the OnSuc­cess and OnEx­cep­tion hooks are still in place, they’re not telling us when the body of the method suc­ceeds or fails but instead, when the state machine cre­ation has suc­ceeded or failed!

image

image

Pretty big bum­mer, eh?

Pro­posed Solution

One way (and the best way I can think of for now) to get around this is to have a spe­cial aspect which works with meth­ods that return Task or Task<T> and hook up con­tin­u­a­tions to be exe­cuted after the returned tasks had fin­ished. Some­thing sim­i­lar to the below will do for the on method bound­ary aspect:

And then you can cre­ate a TraceA­sync attribute that works for async methods:

As you can see from the out­put above, our new OnTask­Fin­ished, OnTask­Faulted and OnTaskCom­ple­tion hooks are cor­rectly exe­cuted after the task returned by the async method had fin­ished, faulted due to excep­tion or ran to completion!

The same approach can also be applied to other built-in aspects such as the Method­In­ter­cep­tionAspect class.

Before you go…

How­ever, there are a two things you should con­sider first before jump­ing into the workaround pro­posed above.

1. if you look at the out­put from the pre­vi­ous exam­ple care­fully, you’ll see that the line “FooA­sync fin­ished” came AFTEREnter­ing Boo” even though from the test code we have awaited the com­ple­tion of FooA­sync before call­ing Boo. This is because the con­tin­u­a­tions are exe­cuted asynchronously.

If this behav­iour is not desir­able to you, there is a very sim­ple fix. Back in the OnA­syncMethod­Bound­Aspect class we defined above, sim­ply add TaskContinuationOptions.ExecuteSynchronously to each of the continuations:

image

2. the pro­posed solu­tion still wouldn’t work with async meth­ods that return void sim­ply because there are no returned Task/Task<T> objects to hook up con­tin­u­a­tions with. In gen­eral though, you should avoid hav­ing async void meth­ods as much as pos­si­ble because they intro­duce some pit­falls which you really wouldn’t want to find your­self in! I’ve dis­cussed the prob­lem with aysnc void (and some poten­tial workarounds) in a pre­vi­ous post here.

 

I hope this post proves use­ful to you, and happy PostSharp’ng! I hear some big things are com­ing in this space Winking smile

Share

Hello!

Just a quick note to men­tion that I will be speak­ing about Aspect Ori­ented Pro­gram­ming at next Saturday’s DDD10 in Read­ing, some great ses­sions in the line up this year, hope to see you there Smile

Share

I gave a talk about Aspect Ori­ented Pro­gram­ming at this year’s DDD South West, the slides is avail­able on SlideShare:

The source code I used can be found here.

 

A big thank you to the guys for mak­ing DDD South West the great event it was and for hav­ing me on-board this year, I had plenty of fun! Hope every­one who made it to my ses­sion enjoyed what I had to say and are think­ing about using AOP in their projects.

If you couldn’t come to the ses­sion I’ll be talk­ing to VBUG Bris­tol on the 13th June so hope to see you then!

Share