Saturday, September 29, 2007

Don’t do modes, mkay? Modes are bad.

 

I recently read Raskins “The Humane Interface“. It’s from 2000 and unfortunately Raskin died in 2005. What a pity, because some of his ideas are truly groundbreaking in the field of usability. While reading, I felt that this book is going to change the way we make not only GUIs but the way we make software as whole. Still, the material that he produced in his lifetime contains enough to keep me interested for … a lifetime.

If you haven’t read it, the basic idea is that we as software people have to know about the basic ergonomics of the mind, just as furniture people have to know about the ergonomics of the body. We can learn about the Ergonomics of the Mind from cognitive science. According to Raskin, the three most important things we learn from them is:

1. We can only focus on one thing at a time. If the message you are trying to convey your user is not at the “locus of her attention”, she just won’t see it. And it’s your fault as the programmer.

2. As we do certain actions repeatedly, they become automatic. Software should try to make it easier for people to learn to automate common tasks.

3. Modes confuse. Caps lock is a good example. Insert/overwrite modes on your keyboard is confusing. Modes in UIs are bad. Don’t do modes.

Ok, so here comes the actual reason for writing a post about this: Richard Raskins son, Aza, is continuing his fathers work, combining many ideas into a product called Enso. Enso is really quite different from other software. It contains a launcher and a spellchecker. So does many other products, but the implementation is way different from anything this far.

The launcher takes over the caps key (it’s only in the way, anyway) and turns it into a command key. While holding it down, you type stuff like “open word”. When you let go of the caps key, Word opens up.

The spellchecker is reached through the “spellcheck” command (using the caps lock key). It spell checks whatever is selected in whatever program is active. This far, only English is supported, though.

It takes a little getting used to, but I’m never gonna uninstall it. And I’m gonna read the book once every year ahead.

And I’m not gonna do modes.

Try it out: Humanized Enso.

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.)

Sunday, May 20, 2007

Finally, a Microsoft-sponsored AOP framework

It came out of the blue. Until the Patterns and Practices group in Microsoft release ThePolicy Injection application block as part of Enterprise Library 3.0, I would have never thought that Microsoft would ever release an AOP framework (or half an AOP frameword anyway). Especially since C# 3.0 and VB.NET 9.0 will introduce extension methods which go at least some of the way to let us inject Cross-cutting Concerns into classes that we don’t own or don’t want to clutter with code.

While mixins give os a way of letting foreign objects implement an interface in an ugly way, extension methods allow us to add new methods to existing classes in a nice looking way. The downside is that extension methods are more limited than mixins. Mixins can contain state, extension methods are just … methods.

AOP frameworks are there to provide two services to the developer: Mixins and interception. So far I’ve talked about mixins, but the Policy Injection application block (PIAB) doesn’t in fact provide mixins capability, only interception. And compared to other AOP frameworks it’s not that feature-rich at all. I still like it and here’s why.

What’s nice about PIAB is the way it’s integrated with the rest of Enterprise Library 3. It comes with ready made handlers that talk to the other blocks: Logging, Exception handling, Authorization, Performance counter, Caching and Validation. These cross cutting concerns cover 90% of what an average enterprise solution needs. And I can add new handlers and insert them into the handler pipeline. Handler code tends to be scattered in funny-named classes. This way it’s easy to organize sensibly.

I can get all that stuff if I’m ready to pay the price. And the price will always be the same (until the CLR starts supporting AOP or we get compile-time AOP like they have in the java world):

AOP is forcing us to 1) let our classes inherit from a certain baseclass, in this case MarshalByRefObject or to make all interceptable members virtual and 2) to never instantiate our objects using the new keyword. Instead an abstract factory is provided as part of the AOP framework. An PIAB is no exception to this rule. If you’re planning to plug PIAB into an existing project to get usage logging for example, you’d be forced to replace every instance of

Customer customer = new Customer();

with

Customer customer = PolicyInjection.Create();

The short term price is doing the search and replace. In the long run, your code gradually becomes more difficult to understand. If someone else from your team doesn’t know the convention to create objects this way, he’ll use “new” and suddenly everybody will be wondering why only some of the customers get intercepted by PIAB.

Mixins are a way to simulate multiple inheritance on an single inheritance runtime. But when PIAB requires us to inherit our business classes from a certain base class, we get no-inheritance instead of single inheritance. That can very well be a price you will be willing to pay, but you need to be aware of this before you decide to use PIAB.

If you’re not willing to pay this price and sell-out on the POCO principles there’s a nice in-between way: You get to choose the base class for your business classes, but then you will only get interception on the members that your class implements from a certain interface, that you specify. Often you’re not in a position to change the base class for foreign classes that you use, so this is a good alternative for those cases. You’ll still have to instantiate using the abstract factory though.

I’m not saying this to critisize PIAB or other AOP frameworks. They are made this way because it’s the only way. They all impose demands that go against POCO. The point is, you’ll want to know the limitations before starting using AOP in general and PIAB in particular. They are almost always mentioned as a footnote on page 64: “Oh by the way, to make any of this work, you’ll have to make all properties virtual and always instantiate objects using our factory.” What if the classes are provided without source code, then I can’t make their members virtual?

Maybe it’s time to reconsider POCO and become less religious about keeping classes clean. I’m looking forward to start using PIAB in the next real world project and to get some hands on experience. Anyway it’s great to know that AOP is moving from the dark-basement-experimental sphere to the enterprise-ready sphere.

For an in-depth discussion of the implementation choices in PIAB, see Ed Jezierski’s post.