“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…

Jimmy Bogard has a very nice summary of steps you can do to speed up building of your project or solution. By “build” I mean not just rebuilding solution from scratch, but doing also a complete run down: cleanup, rebuild and run your tests. This can be a local build performed on a developer’s machine, or a continuous integration build performed by dedicated build/integration server.

Some time ago, when build times grew to intolerable limits, we cut down number of projects in our solution. Along with a common output folders, this improved dramatically performance especially on integration server, where a single committed change threw running of few cascading builds and code analyses.

Now, slowest part of our build process are integration tests. A big part of them are “testing integrations” with database. Since we’re using real MS SQL Express 2008 instances to run them, tests are very slow. A natural solution is using of an in-memory database like SQLLite. We spent some time on this, but since our database interactions are not trivial (kind of multi-tenant & multi-database application) we gave up until better times. But I think we will be back to finish that, because with more tests written we’re pushing up build times. To give an idea how this can be done, Ayende Rahien has a very basic example how to use in-memory database to run NHibernate integration tests.

If it will be only one conference that I’d be allowed to attend during one… no, two… tree… years it will be the Norwegian Developers Conference 2009.

Absolutely fantastic speakers line-up:

  • Jeremy Miller
  • Ayende Rahien
  • Glenn Block
  • Robert C. Martin
  • Jimmi Nilsson
  • Udi Dahan
  • … and more…

Each of these speakers are well known in software development community by their contributions to open-source projects or by efforts they do to promote best values and practices in software engineering, sharing experience and teaching mere mortals.

Extraordinary agenda, tracks and talks. If I’d be able to go there, sure I’ll find a way to divide myself to see as much possible parallel tracks.

If you’re searching for best investments for your money in a tough economic climate, you’ve found it: your skills and Norwegian Developers Conference.

Ayende is running a series of posts detailing and explaining how NHibernate maps entity classes to database. Posts include XML mappings, code and SQL queries generated when saving or querying the database so that you have everything to understand what NHibernate do to persist your data. The series is a nice addition to NHibernate Reference Documentation.

NHibernate Mapping:

 

It was a nice reading. I’ve refreshed few things in my memory and learned few new tricks.

This post will be updated as new chunks will be published (I hope it will) by Ayende.