First of all, Steve Strong made a Christmas gift to community by presenting a new Linq implementation for NHibernate, which is now incorporated in the trunk. Kudos for a such great work!

Another valuable addition to NHibernate is the QueryOver<T> API that wrapped ICriteria API and made it easier to use. Thanks to Richard Brown.

Both features are not crucial for the success of NHibernate, but they are very nice improvements that will attract new users and will keep the old ones. It’s easier to advocate for NHibernate when you can point not only at his advanced features. The hype around Linq makes difference when features are compared. Having a provider for NHibernate will be a strong decision argument.

I hope that soon after New Year’s holidays I’ll try to switch to NHibernate 3.0. If migration of our project will be painless and all tests will still green, I think we’ll run with the trunk. It’s the least we can do to help make this project better.

… more a note for myself

Found a discussion that gives a few very nice examples of WPF applied in real world, line-of-business applications: WPF LOB samples.

I can’t stop be amazed by what degree of flexibility WPF is giving to designers and application developers. Having an artistic sense and willingness to create “something” you can do really nice, usable & nice looking applications.

 

Update: reviewed some of my notes, found another great LOB sample, not listed in previous discussion: Great User Experience Example in a Business Application.

Running with scissors

Yesterday I have participated at my second meeting of ALT.NET community in Switzerland. The ALT.NET Swiss group was running for some time, but I’ve discovered it recently, after being contacted by Frédéric SCHÄFER from OCTO Technology. He started the group and has been organizing meetings in Lausanne and Geneva. Many thanks Frédéric and keep up a good job!

First meeting I attended was about WPF and Model-View-ViewModel pattern implementation. It was held by Frédéric SCHÄFER. He took a simple WPF application and slowly modified it to use MVVM pattern. That got us better separation of concerns and maid application more testable.

The yesterday’s meeting was for me a special one, I was one of the speakers.

I’ve talked briefly about how the MVVM pattern is used with WPF, showed a “classical” implementation of it and after that presented some improvements over that. The initial ViewModel had INotifyPropertyChanged  implemented and used ICommand to respond to UI actions initiated by view. For two properties and a command there was a lot of “ceremony” – code being there just to comply with implementation requirements. At the end of the session, by using two frameworks(BLToolkit and Caliburn) , I’ve managed to reduce the volume of the code by the half while maintaining initial functionality. Why is this important? Shorter code means less place to make a mistake, hide a bug, it’s faster to read and understand. I will write a separate blog post about my solution.

The other speaker was Daniel Vaughan, the author of Calcium SDK. He spoke about Calcium SDK, which is a set of additional services and modules built on top of the Prism (Composite WPF) and few Visual Studio templates to make creation of composite application easier. After that, he talked about compile time validation of WPF’s binding expressions. This, being a real headache for WPF developers, was addressed by Daniel by using template engine backed into Visual Studio – T4. His solution is very interesting. He generates some metadata classes with static properties and after that uses them in binding expressions. I’m still not sold on the whole idea, but I should spend some time playing with it. But presentation was nice, thanks Daniel!

It was a great evening. It’s always interesting to meet people with different set of skills and experience, you can look at known problems from other angles, getting suggestions or criticism. Or you just can learn something new.

Special thanks to Atif Aziz and Cargill International SA for hosting the session.

“why is this a problem?” may ask you…

Let’s review the ways that NHibernate lets you register your own event listeners. You can do it in configuration file:

<listener class=”NHTest.Listeners.CustomSaveEventListener, NHTest” type=”save” />

… or in code:

Configuration cfg = new Configuration();
cfg.EventListeners.SaveEventListeners =
    new ISaveOrUpdateEventListener[] {new CustomSaveEventListener() };

Nice, so far…

It’s not if you want to add a listener, not to replace them. Both registrations are just replacing default event listeners with your own implementations. Very often it’s not want you want!

In our case, we want default listeners do the job and just add few our own listeners to run the business. No problem, let’s code:

var listeners = configuration.EventListeners;
listeners.SaveEventListeners =
    new List<ISaveOrUpdateEventListener>(listeners.SaveEventListeners)
    {new CustomSaveEventListener()}
    .ToArray();

 

Since I wrote that code some day I hated it. Too verbose, too obscure, hard to read & understand. But event registration infrastructure doesn’t offer an easy and simple way to add a listener. Few times I tried to come with a nice solution for that, even tried to modify NH’s code.

Today, I’ve done it:

configuration.AddListener(el => el.SaveEventListeners, new CustomSaveEventListener());

Some expression’s magic and we end up with a very clean & readable code.

Implementation:

public static class NHibernateConfigurationExtensions
{
    public static void AddListener<TListener>(
        this Configuration configuration,
        Expression<Func<EventListeners, TListener[]>> expression,
        TListener listenerImpl)
    {
        var propertyInfo = ReflectionHelper.GetProperty(expression);
        var existentListeners = (TListener[]) propertyInfo.GetValue(configuration.EventListeners, null);
        var newListeners = new List<TListener>(existentListeners) { listenerImpl }.ToArray();
        propertyInfo.SetValue(configuration.EventListeners, newListeners, null);
    }

    public static void AddListeners<TListener>(
        this Configuration configuration,
        Expression<Func<EventListeners, TListener[]>> expression,
        IEnumerable<TListener> listeners)
    {
        foreach (var listener in listeners)
        {
            configuration.AddListener(expression, listener);
        }
    }
}
Have a nice day...

Having to group a collection shown in UI by a command fired from the View, I’ve came to a nice solution by writing an extension method to the ObservableCollection<T> class.

The extension method:

public static class ObservableCollectionExtensions
{
    public static void VisualGroupingBy<T>(this ObservableCollection<T> collection,
                                           Expression<Func<T, object>> groupByExpresson)
    {
        var view = CollectionViewSource.GetDefaultView(collection);
        collection.VisualGroupingClear();

        var propertyName = ReflectionHelper.GetPropertyName(groupByExpresson);

        view.GroupDescriptions.Add(new PropertyGroupDescription(propertyName));
    }

    public static void VisualGroupingClear<T>(this ObservableCollection<T> collection)
    {
        var view = CollectionViewSource.GetDefaultView(collection);
        view.GroupDescriptions.Clear();
    }
}

 

How to use it:

public ObservableCollection<Address> Addresses { get; set; }
public void GroupAddressesByCity()
{
    Addresses.VisualGroupingBy(address => address.City);
}

Clean, no magic strings, readable…

… and his “clever” UI:

The error is that control interfaces must not be intelligent. Briefly, intelligent user interfaces should be limited to applications in which the user does not expect to control the behavior of the product. If the product is used as a tool, its interface should be as unintelligent as possible. Stupid is predictable; predictable is learnable; learnable is usable.

Continue reading: Wolfram Alpha and hubristic user interfaces.

… was to choose Microsoft’s implementation if Ribbon to use in our current development. Yes, I knew it was released as beta. But I hoped to have frequent enough releases from MS to keep up with user’s feedback & fixing bugs. It was my error.

The usual feedback from MS on questions and bug reports is:

Thanks for reporting this issue.  This is a known issue and will be addressed in our V1 release.  In the meantime, unfortunately, you’ll only be able to … until we release a fix.

The problem is that the Ribbon was released in October 2008. Since then, nothing like a bug fix release was provided. No known date of the next version to be released. No intermediary releases with bug fixes. Nothing.

We lost significant time working around bugs & bad implementation. It’s completely my fault. I should choose a commercial component to achieve our goals.

Do you want to know my second biggest failure?

Choosing for our project WPF Themes also provided by Microsoft. Why it failed? See above. Bugs that make you spend time fixing weird behaviors instead of providing value for the client.

What I’ll do now with all this crap in our projects? I don’t know yet. But I know for sure, that I’ll never ever use any betas (of developer products) provided by Microsoft in a real development. At the end it costs you too much…

A snippet from a project I’ve been reading:

// -- FILE ------------------------------------------------------------------
// name       : UserConfig.cs
// created    :
// language   : c#
// environment: .NET 2.0
// --------------------------------------------------------------------------
using System;

namespace TheNamespace.Configuration
{

    // ------------------------------------------------------------------------
    public class UserConfig
    {

        // ----------------------------------------------------------------------
        public UserConfig( System.Configuration.Configuration configuration )
        {
            if ( configuration == null )
            {
                throw new ArgumentNullException( "configuration" );
            }

            this.configuration = configuration;
        } // UserConfig

        // ----------------------------------------------------------------------
        public System.Configuration.Configuration Configuration
        {
            get { return this.configuration; }
        } // Configuration

        // ----------------------------------------------------------------------
        public string FilePath
        {
            get { return this.configuration.FilePath; }
        } // FilePath

        // ----------------------------------------------------------------------
        // members
        private readonly System.Configuration.Configuration configuration;

    } // class UserConfig

} // namespace TheNamespace.Configuration
// -- EOF -------------------------------------------------------------------

 

It’s a matter of taste, of course, but I’m wondering, what is the reason to decorate the code with a such ceremony?

Much of the time we, developers, are spending reading the code. That’s why the code that is clean, easy to read and understand is so much appreciated.

Heard today, from devs working on an old & big project:

Hey, please open that file at line 11108 and try…

That’s… breathtaking…

To be clear, they are talking about source code file from a project that is in continuous maintenance mode, with new functionality and bug fixes added with regularity.

 

Definition

Technical debit – obligation that a software organization incurs when it chooses a design or construction approach that’s expedient in the short term but that increases complexity and is more costly in the long term.

Technical debit by Steve McConnell:

If the debt grows large enough, eventually the company will spend more on servicing its debt than it invests in increasing the value of its other assets. A common example is a legacy code base in which so much work goes into keeping a production system running (i.e., “servicing the debt”) that there is little time left over to add new capabilities to the system.

The success of user interface is not only in visual design, but also in user interactions. Usability, along with generic application usefulness, will define final user satisfaction & overall experience when working with your application.

Any developer occasionally or permanently is playing to role of user interface and interactions designer. Every time you are spiking an UI prototype or creating a data entry form we should keep in mind the user, usability and characteristics of successful user interface. What they are?

User interface should be:

  • Clear
  • Concise
  • Familiar
  • Responsive
  • Consistent
  • Attractive
  • Efficient
  • Forgiving

Read more, with details in 8 Characteristics Of Successful User Interfaces.

Take care of the users. At the end, they are paying your wages…