Saturday, August 25, 2007

Fresh AOP meat on the dish

Old news to you, maybe, but news to me. And good news if you are just a little bit tired of the usual drawbacks of AOP using subclassing or proxies. In a previous post I discussed these problems with respect to the Policy Injection App Block in Enterprise Library 3.

Check out the PostSharp project. It uses MSIL post compilation. That means that after the c# compiler has finished compiling you code, PostSharp compiles it again to inject your interceptors. Very interesting in its own right.

One of the interesting spin-offs of PostSharp is called PostSharp4EntLib and is part of the EntlibContrib project. It makes it easier to have your Enterprise Library policies injected into your entities. Not runtime, but compile time. And you don’t even need to inherit from MarshalByRefObject and wrap all instantiations in ugly calls to abstract factories anymore. PostSharp takes care of this for you.

Only one hurdle so far: It will not recognize Danish characters in my identifiers. This minor setback can’t hurt me though. Even though it’s not reached production level stability, I’m going to try it out soon in an enterprise project.

Stay tuned for further details.

6 Responses to 'Fresh AOP meat on the dish'

Subscribe to comments with RSS or TrackBack to 'Fresh AOP meat on the dish'.

  1. Thomas Jespersen said,

    ON AUGUST 29TH, 2007 AT 5:36 PM

    Interesting!

    I wonder what the debugging experience is like!

  2. azza gregg said,

    ON SEPTEMBER 18TH, 2007 AT 9:54 AM

    I’ve just started using it for the last week to implement logging throughout a multi-tiered asp.net 2.0 web application and I’ve found it easier to implement than the Microsoft Policy Injection Block.

    As for Thomas’ comment, debugging is as normal however it looks like the post-compilation prevents you from being able to use the edit&continue VS2005 feature.

    I’m almost finished, which unfortunately means I might have to roll-back because lost of posts out there mention it being not ready for production yet (doh!!!).

    Looking forward to the next release, huge thanks to Gael Fraiteur!!

  3. Soren said,

    ON SEPTEMBER 18TH, 2007 AT 7:58 PM

    In the meantime I’ve had some experience with debugging using VS2008. It’s better than all other AOP frameworks I’ve encountered, but still not 100%. Debug symbols are moved along with the code, so in 8 out of 10 exceptions will take the debugger to the right place in code.

    But the last 2 tenths it will just give you a TargetInvocationException. Especially RuntimeInitialize() calls and static constructors are difficult.

    Azza, bad news about edit and continue. I guess I’ve gotten used to not having that — it’s not working in VS2008 :(

    Could you post the urls for the posts that doubt PostSharp quality, please? I’m close to going production with it… Thanks!

  4. azza gregg said,

    ON SEPTEMBER 20TH, 2007 AT 8:51 AM

    Hi Soren,

    I’ve finished a first round of testing the Laos and Public namespaces and haven’t had any further issues which may mean this’ll go to test and production with the next release.

    Sure you get those TargetInvocationExceptions, I was thinking about using the OnMethodBoundaryAspect to capture the OnException event and see if there’s more detail to be found…

    My hesitation comes as a matter of caution when using something that still has the words ‘Beta’. I haven’t found anyone out there mentioning production implementation but did find the following link discouraging it;

    http://doronsharp.spaces.live.com/blog/cns!E19CE2289AB7F8C1!137.entry

    Enjoy VS2008…

  5. Soren said,

    ON SEPTEMBER 20TH, 2007 AT 3:47 PM

    Azza, the blog post you refer to is from February when PostSharp was in alpha. It’s in beta3 now.

    What’s more important than the official state (CTP, alpha, beta etc) is Gael’s willingness to provide support very quickly. And right now, he’s very dedicated to the project.

    I’m planning to (very cautiously) take PostSharp into production months.

    Regs, Søren

  6. azza gregg said,

    ON SEPTEMBER 24TH, 2007 AT 4:18 AM

    Cheers Soren, I’m starting to feel a lot more confortable with this great peiece of software.

    Regarding the TargetInvocationException, I’ve put a simple loop into the catch block that compares the InnerException to null and assigns to an exception variable. When the code breaks out of the loop we now have the actual Exception that was originally thrown.

    Azza.

LINQ to POCO?

I recently had the opportunity to try out LINQ for SQL beta 2 in a real world (though still small scale) enterprise solution. It’s been a while since I took an early CTP for a spin, so I was excited to finally have a go.

I used the Domain Model tool integrated into VS 2008 to have tables mapped into partial classes automatically. That worked like a charm. If any of my observations apply only to the Domain Modelling tool, and not to LINQ2SQL in general, I apoligize in advance. I’m not (yet) a LINQ expert…

I’m often concerned about the restrictions that different O/R mappers impose on your freedom to keep a clean, simple and efficient class design (otherwise known as POCO / Plain Old Clr Objects). My first impressions of LINQ in this regard, are these:

1. I love the embedded query language, and the code completion is good.

2. Association properties cannot be read only, thus preventing immutable properties. Immutable classes or immutable properties are fundamental to creating a clean, domain driven design.

3. You cannot add [Attributes] to the autogenerated properties, since partial properties are not supported in C#3. So you cannot use Enterprise Library’s attribute based validation framework, or some custom framework that uses attributes as the only interface. Xml serialisation can be tricky as well.

4. Autogenerated fields do not follow MS naming conventions which says fields should be camel cased. A property called Horse will have a corrensponding field named _Horse. Not critical but not very pretty either.

5. Associations require an additional property to hold the foreign key value. It can be private, but not omitted. One to many associations always have a parent property, only the child collection is optional. This forces the domain model to include something, which is not an intrinsical part of the domain: Foreign key values. They are there only to satisfy LINQ, so the domain object end up not being very Persistence Ignorant.

6. Even non lazy loadable associations are wrapped in an EntityRef. Not very POCO.

7. The same goes for collections, which are always of a specific type, EntityCollection. So no coding against interfaces or ReadOnlyCollection or custom collection types.

8. Objects that are constructed within a query are tracked automatically. It took me a while to realize why too many rows were being inserted in the database: I had created some of them to be temporary, but LINQ tracked them all and found them to be transient, therefore inserting them into the database.

9. In order for tracking to work, your classes must implement INotifyPropertyChange. Yet another restriction on my classes. They started out pretty POCO, but it all adds up to a very non-POCO feel.

Conclusion: That’s all for the first day with LINQ 2 SQL. Possibly, more issues will surface along the way, without doubt. These first issues are worth being aware of, as O/R mappers can make your life easier (particularly in small scale projects.) And a lot more difficult (typically in larger projects.)