Archive

The benefits of unit testing are numerous. When aspects are involved, Matt Groves believes keeping them "thin" is key to keeping your code easy to unit test and he explores some of the implications of unit testing when a post-compiler tool is involved.

Gael Fraiteur joins this final episode in the AOP in .NET series to give his differing opinion about the relevancy of "thin" aspects and speaks about a set of practices that can be used to create efficient tests of aspects.

Q&A

Q: What would be the best way to inject the cache provider VIA an IOC container? (e.g. Autofac/Unity)

A: Whatever container you wish to use is fine. In my example I just new them up directly but in reality you shouldn't do that. In structure map you could say:

if (!On) return; 
_concern=ObjectFactory.GetInstance<ICacheConcern>();

As long as you're not tying it to a specific implementation, you're just asking for something that implements the interface. This is known as the service locator pattern.

Q: Gael, you mentioned in your presentation that one can't test an aspect in isolation of a target. Isn’t that exactly what Matthew just showed us?

A: Gael – yes, but Matt showed it in a very specific case using compiler internals to do it by instantiating the execution arguments that are being passed to the aspect. In the case of OnMethodBoundary Aspects, this is very simple to do, but if there are changes in methods or invocations it can become quite complex.

Matt showed how to isolate the aspect completely from the aspect framework with the notion of thin aspects but to me the cost of doing so is huge. There is the abstraction that is added on top of the aspect which isn’t justified because test coverage is worsened and the meta data is part of the input. Just as you wouldn’t test a method without an argument, you wouldn’t test an aspect without a target.

Matt – what I tested in isolation wasn’t an aspect but rather the advice or the actual logic of the aspect.

Gael – Matt’s approach may work in simple cases but I would be curious to see how it works in complex aspects, including aspect combinations.

Q: Why would you use a static IOC resolution instead of using the service locator with each call of "OnEntry"? (in the logging example)

A: This is a matter of optimization. Logging is very performance sensitive, because it’s invoked at a very high frequency, so I would avoid resolving dynamically but this is entirely up to you. In documentation, I show several approaches where the service locator returns a delegate that may be re-evaluated each and every time (or not, depending on your preference).

There is no general rule or best practice here, it depends on what you want to achieve in each situation and the tradeoffs between architecture and performance.

Q: Gael, you mentioned in your presentation that you can’t unit test build-time logic because PostSharp performs code weaving at compile-time. For a consumer of a class or a framework, why would I be concerned on how the deliverables are made instead of how they are used?

A: It depends on who the consumer is. In large teams, you’re delivering aspects to the rest of the team and not the end customer. With some of our largest customers 10% of the team build aspects and the other 90% consume the aspects. In those cases, if you want your team to be more productive then you need to check that the aspect has correct build-time behavior. Then the problem is: how to test validation.

If however your aspect never emits build-time errors, then run-time testing may be sufficient.

Q: Couldn't you unit test the aspects advice the way Matthew suggests, and then integration test the combination and ordering of method calls of the aspects the way Gael suggests? Do these techniques really need to be mutually exclusive?

A: Gael – it depends on what your objective is. If your objective is to decouple the framework from the aspect, then Matt’s approach may be useful. However, if the objective is to do good testing in as little time as possible then why would I add complexity and decouple the framework from the aspect? I don’t see the benefit in terms of architecture and time-savings.

Matt – Gael and the PostSharp team take a different approach than I would because they’re writing aspects for the general public to consume and not just my team.

Q: In the case of injected concerns/dependencies for aspects, would you use a fake resolver?

A: Matt – in my case the aspect was thin enough so I didn’t have to use a fake resolver. What I did instead was to pass-in mock objects directly, injecting them myself.

Gael – you should have your resolver work differently, depending on the context. In production, you would involve your real resolver and in testing you would add rules. and according to the context to which the aspect is being applied, it would return a different implementation of the service. these are all options to consider.

Q: Have any of you used something like nCrunch with PostSharp?
A:
Matt – I’ve used nCrunch before, it’s a great test runner tool, and haven’t had any problems with using it and PostSharp together. However it’s been a while since I last used it.

Many thanks to Matthew Groves for the wonderful 5-part series. We wish him much success with his new book, Aspect-Oriented Programming in .NET, out this month. You can see Matt speak and catch up with him in person this summer at Louisville .NET Meetup Group and CodeStock.

Alex Papadimoulis of The Daily WTF fame will join us on June 27th for the next PostSharp Live Webinar to talk about NuGet, deployment management issues, and private repositories as a possible solution.

More on that coming very soon.

-Britt

prague_flood

When I first moved to Prague in 2004 I heard many tales from locals about the devastation caused by the floods of 2002 which killed 17 people, forced tens of thousands from their homes and caused several billion dollars of damage across the country.

I heard tales of rescue: brave souls risking their own lives to save elderly neighbors and pets.

Tales of losing it all: families without homes and cars; historic photo albums, artwork and libraries of books now gone forever.

And tales of starting over: communities coming together in solidarity to rebuild their lives; a city slowly restoring to its former beauty, one street at a time.

I remember thinking to myself, “thank god flooding like that only happens every 100 years.”

Just yesterday, Czech Prime Minister Petr Necas declared a state of emergency for most of the nation as swollen rivers caused by days of heavy rain threatened Prague's historic center and forced evacuations from low-lying areas.

And the waters are STILL rising.

In an effort to support the beautiful city to which we call home, and all those affected by the current Prague flooding, PostSharp Technologies is donating 50% of all online purchases to a local flood relief fund from now until the state of emergency is lifted.

Please keep the city of Prague and the Czech nation in your thoughts and prayers during this difficult time, and we will keep you updated on Twitter as news comes in.

Now is our chance to be part of a new tale.

-Britt

 

Tools like PostSharp, that manipulate the IL, can seem like black magic at first. However, the simple act of opening a decompiler changes all that. In this episode, Matt Groves shows how to decompile a .NET assembly and view code with/without a PostSharp aspect using Reflector to see exactly what’s being manipulated.

Q&A

Q: In your previous session, you used aspect boundaries to do something that could also be accomplished by method interception. What factors help to decide which way you should implement?

A: The OnMethodBoundaryAspect offers higher performance because only a part of the calling context needs to be passed to the aspect. This is especially true with the aspect optimizer feature, included in PostSharp Pro and Ultimate, when the aspect does not consume a lot of context, for instance a transaction scope aspect. The benefit is reduced however if the aspect consumes a lot of context, for instance all argument values. The MethodInterceptionAspect is more powerful: you can invoke the intercepted method on a different thread, for instance. But it is slower because the whole calling context needs to be stored to the heap and passed to the aspect.

Q: How can I disable a PostSharp aspect temporarily?

A: There are a number of ways to disable PostSharp from a specific project:

  • In Visual Studio, open the project properties dialog, select the right configuration, open the PostSharp tab page, and change the value of the Disable PostSharp option.

  • In Visual Studio, open the project properties dialog, select the right configuration, open the Build tab page, and add the conditional compilation symbol SkipPostSharp.

  • Define the MSBuild property SkipPostSharp=True, for instance using the command line msbuild /p:SkipPostSharp=True.

Q: Which Aspects are serialized?

A: Every aspect is serialized at compile time. You can find out more on aspect serialization in PostSharp documentation.

Q: Is there deserialization during run-time?

A: Yes, by using a decompiler you will see that PostSharp stores serialized aspects as resources, for instance the aspect I applied to the DoSomething method in the video, and an internal class does the work of deserializing the resources into an object.

Q: Why are you using the objects (internal classes) instead of writing the code directly in the corresponding methods? Wouldn't that be more performant?

A: This approach is named “aspect inlining”. It is more performant but more complex and less powerful (aspects code would need to be more limited).

Q: System.Diagnostics.Contracts also uses the post-compiler rewrite method to check state and assertions. Do PostSharp and Contracts work well together?

A: Yes, they work well together. PostSharp runs after Code Contracts.

Q: It’s evident that PostSharp is heavily dependent on using .NET's underlying support for discovering and calling methods using Reflection. Are there any significant trade-offs or compromises in using Reflection so heavily?

A: PostSharp does not rely on reflection to discover and call methods. The analysis is done completely at build time, and PostSharp generates code to call exactly the right methods. Reflection is only used if the aspects themselves use reflection. Even then, any use of reflection is optimized and cached.

Up next: Unit Testing & Thin Aspects

The benefits of unit testing are numerous. When aspects are involved, Matt believes keeping them "thin" is key to keeping your code easy to unit test. Join us this Thursday as he explores some of the implications of unit testing when a post-compiler tool is involved.

During this final episode in the AOP in .NET series, Matt will be joined by Gael Fraiteur, the creator of PostSharp, who has a differing opinion about the relevancy of "thin" aspects and will speak about a set of practices that can be used to create efficient tests of aspects.

SPECIAL OFFER:

The generous folks at Manning Publications are offering a 40% discount on Matt’s new book to all live webinar attendees. So, if you want to learn what difference AOP and PostSharp can make in your projects, and take advantage of Manning’s discount offer, be sure to join us for the last live webinar in this series.

Seats are limited and this head-to-head episode is sure to sell out so reserve your spot today.

-Britt