Archive for October, 2009

Slutty Types

23 commentsWritten on October 11th, 2009 by
Categories: Software Development

Slutty Types are types which:

  • give you access to their privates without too many difficulties
  • don't really care about your intentions, or if they do, aren't very clear on that
  • occasionally seem like a good short-term fix
  • can be used in a variety of ways, with different outcomes and none of them are guaranteed
  • can not to be trusted
  • really need to be tested
  • will burn you sooner or later if you're not careful
  • become even more of a mess during the aging process

Feel free to add to the list :)

Event Aggregation

7 commentsWritten on October 9th, 2009 by
Categories: Patterns, Silverlight

We're experimenting at work with a bit of a different approach as to how we structure our views and how they will interact with each other. We already know that our views will be reused in many different contexts so having them communicate with other views is something that needs to be done in a very loosely coupled manner. I don't want any of the views to even know about the existence of other views, let alone having them know about specific instances of them.

But these views do have to interact with each other. I didn't want to use typical events because that would require either a certain view to know about another view to be able to subscribe to its events, or you'd need some other component which knows which views need to be hooked to each other. We really need maximum flexibility for what we have in mind with our views, so it only made sense to finally start using the Event Aggregation pattern. The idea is that a view can basically publish events, without knowing who is subscribed to these events, and that suscribers will be notified whenever these events occur. However, subscribers don't know anything about who is publishing the events. Instead, both publishers and subscribers only know of the Event Aggregator. A publisher tells the aggregator to publish an event to all subscribed listeners for that event. Each subscribers simply tells the aggregator "i'd like to be notified whenever this event occurs, and i don't care where it comes from".
Plenty of implementations of this pattern can be found online already, so i figured: why not add my own? :p

Fist of all, an event is nothing more than a class that inherits from this class:

    public abstract class Event {}

Every event should inherit from this class, and add whatever necessary properties that are important for that particular type of event.

If a class is interested in listening to a specific event, it needs to implement the following interface:

    public interface IListener { }
 
    public interface IListener<TEvent> : IListener
        where TEvent : Event
    {
        void Handle(TEvent receivedEvent);
    }

If a class is interested in multiple events, it simply needs to implement the generic IListener interface for each type of event that it wants to handle.

Then we obviously need the Event Aggregator. I wanted an aggregator that allowed listeners to either subscribe/unsubscribe to/from very specific events, or just subscribe/unsubscribe to/from whatever it supports. So i have the following IEventAggregator interface:

    public interface IEventAggregator
    {
        void Publish<TEvent>(TEvent message) where TEvent : Event;
        void Publish<TEvent>() where TEvent : Event, new();
 
        void Subscribe(IListener listener);
        void Unsubscribe(IListener listener);
 
        void Subscribe<TEvent>(IListener<TEvent> listener) where TEvent : Event;
        void Unsubscribe<TEvent>(IListener<TEvent> listener) where TEvent : Event;
    }

The Subscribe and Unsubscribe methods that simply take an IListener reference will either subscribe or unsubscribe the given listener to/from every event that it can handle. In other words, for every generic IListener interface that it implements. Yet you also have the ability to subscribe/unsubscribe from a specific event type.

And here's the implementation:

    public class EventAggregator : IEventAggregator
    {
        private readonly object listenerLock = new object();
        protected readonly Dictionary<Type, List<IListener>> listeners = new Dictionary<Type, List<IListener>>();
        private readonly IDispatcher dispatcher;
 
        public EventAggregator(IDispatcher dispatcher)
        {
            this.dispatcher = dispatcher;
        }
 
        public virtual void Subscribe(IListener listener)
        {
            ForEachListenerInterfaceImplementedBy(listener, Subscribe);
        }
 
        public virtual void Unsubscribe(IListener listener)
        {
            ForEachListenerInterfaceImplementedBy(listener, Unsubscribe);
        }
 
        private static void ForEachListenerInterfaceImplementedBy(IListener listener, Action<Type, IListener> action)
        {
            var listenerTypeName = typeof(IListener).Name;
 
            foreach (var interfaceType in listener.GetType().GetInterfaces().Where(i => i.Name.StartsWith(listenerTypeName)))
            {
                Type typeOfEvent = GetEventType(interfaceType);
 
                if (typeOfEvent != null)
                {
                    action(typeOfEvent, listener);
                }
            }
        }
 
        private static Type GetEventType(Type type)
        {
            if (type.GetGenericArguments().Count() > 0)
            {
                return type.GetGenericArguments()[0];
            }
 
            return null;
        }
 
        public virtual void Subscribe<TEvent>(IListener<TEvent> listener) where TEvent : Event
        {
            Subscribe(typeof(TEvent), listener);
        }
 
        protected virtual void Subscribe(Type typeOfEvent, IListener listener)
        {
            lock (listenerLock)
            {
                if (!listeners.ContainsKey(typeOfEvent))
                {
                    listeners.Add(typeOfEvent, new List<IListener>());
                }
 
                if (listeners[typeOfEvent].Contains(listener))
                {
                    throw new InvalidOperationException("You're not supposed to register to the same event twice");
                }
 
                listeners[typeOfEvent].Add(listener);
            }
        }
 
        public virtual void Unsubscribe<TEvent>(IListener<TEvent> listener) where TEvent : Event
        {
            Unsubscribe(typeof(TEvent), listener);
        }
 
        protected virtual void Unsubscribe(Type typeOfEvent, IListener listener)
        {
            lock(listenerLock)
            {
                if (listeners.ContainsKey(typeOfEvent))
                {
                    listeners[typeOfEvent].Remove(listener);
                }
            }
        }
 
        public virtual void Publish<TEvent>(TEvent message) where TEvent : Event
        {
            var typeOfEvent = typeof(TEvent);
 
            lock (listenerLock)
            {
                if (!listeners.ContainsKey(typeOfEvent)) return;
 
                foreach (var listener in listeners[typeOfEvent])
                {
                    var typedReference = (IListener<TEvent>)listener;
                    dispatcher.BeginInvoke(() => typedReference.Handle(message));
                }
            }
        }
 
        public virtual void Publish<TEvent>() where TEvent : Event, new()
        {
            Publish(new TEvent());
        }
    }

In case you're wondering... the IDispatcher interface is merely a way to wrap Silverlight's real Dispatcher. We wrap it so we can use a different implementation of the IDispatcher in our automated tests. Other than that, the implementation is very straightforward.

We started using this very recently, so this implementation might change in the upcoming weeks, but for now it does what it needs to do and it does so pretty well. In our case, every view's Presenter automatically has an IEventAggregator property so whenever we need to publish an event, we can simply do something like EventAggregator.Publish(new SomeEvent(someParameter)). Or, Presenters that need to listen to events can simply say EventAggregator.Subscribe(this) or only subscribe to some specific events whenever they need to and their specific Handle method will be called whenever someone publishes the event. This also allowed us to get rid of the somewhat awkward syntax when testing events (subscription, unsubscription and the actual handing of events) with mocking frameworks.

And as a last bonus, i put a call to the Unsubscribe(IListener) method in the Dispose method of our base Presenter implementation. Which means that none of them will be left subscribed to events by accident anymore :)

Thoughts On Intellectual Honesty And Personal Ambitions

1 Comment »Written on October 4th, 2009 by
Categories: Opinions, Rants, work/career

One of my favorite topics discussed in the classic Code Complete book (simply a must-read for every developer) is that of Intellectual Honesty. It basically means being honest about what you know, what you don't know, what you can do and what you can't do. It also means that you need to be able to give credit where credit is due, and that you as a developer need to be able to accept solutions to problems no matter where they came from, even if it wasn't your idea or if the idea/solution comes from someone you might not always agree with.

I've always thought that Intellectual Honesty is a very important trait that every developer needs to have. I also believe that it is too frequently missing in this business. Some people just want (or need) to be right all the time, even if they are wrong. In software development, it's generally in everyone's best interest to go with the best possible solution to a given problem, while still keeping all relevant constraints in account. Some developers have a genuine interest in the architecture that is used and how things should be done. That is obviously a good thing and i wish there were more developers like that.

I'm in a position where i have a lot of influence on architectural decisions and how we should develop our code. But i've never wanted to be the only one who had to make these decisions, nor do i want people to just go ahead with every idea that i have. I want people to get involved with these things. I want feedback. I want to hear ideas from other people that are better than my own. It's better for everyone if multiple people are involved in such discussions and decisions. Get a couple of people together, discuss things, go over the options and eventually pick the best proposed solution no matter who came up with it. That's always been my approach and it always will be. And i truly believe that it's a healthy approach for everyone involved.

But there are always people who either want to be the only one who gets to decide these things, without input from others, or are generally unhappy in their job if they believe their ideas aren't being considered.

My question to these people is: why? Why does it matter if another person's solution is chosen? Why would you need to be frustrated or disgruntled if your solution wasn't chosen? If you're working for a company where your ideas aren't even considered then sure, you have every right to be frustrated or disgruntled (and i should know, because i've worked in such a place in the past). But if you're working for a company where you know full well that everyone's ideas are considered, then you really have no reason at all to complain if your solution wasn't accepted.

Unless of course, you are more concerned about your personal ambitions instead of the actual results. If all you care about is your status, position or whatever you want to call it, then you really are in the wrong business. Sure, there are companies where you can make quite a career out of such an approach, but it's just not healthy. Not for you personally, nor for your employer, nor for your customers. It doesn't help anyone but yourself, and that sure as hell won't last forever.

Be honest, at least to yourself and preferably to the people you work with as well. If your ideas don't make it, then you might need to question your approach (and for some people specifically: your tactics), your real motivations, or perhaps even your skill level. Again: be honest about what you can do, what you can't do, what you know and what you don't know. And learn how to work with other people, instead of simply trying to get ahead of them.

I'd like to end this post with a quote from Dale Carnegie:

Any fool can defend his or her mistakes, and most fools do.

Why NHibernate Entities Need A Public Or Protected Parameterless Constructor

4 commentsWritten on October 4th, 2009 by
Categories: NHibernate

I have an older post where i discuss how you can implement a Value Object with NHibernate. In that post i mentioned the following:

NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient.

I got the following comment from someone:

I too am trying to determine how well NHibernate lives up to the promise of persistence ignorance. I can definitely live with unnecessary private constructors, but I’m dubious about adding protected constructors just to support an ORM.At any rate, I was surprised by the sentence I quoted, because I didn’t realize there were any circumstances in which NHibernate required protected default constructors.

Once again, the answer is related to the dynamic proxies that NHibernate uses. Value Objects will never be proxied by NHibernate, so NHibernate only needs a private default constructor to create the instances. If an entity is eligible for lazy loading however, then NHibernate will create a type which inherits from your entity (this is described in depth here and here). Which means that we really need either a public or protected constructor in entity classes that are eligible for lazy loading. Consider the following class:

    public class SomeEntity
    {
        public SomeEntity(string someRequiredValue)
        {
        }
 
        private SomeEntity()
        {
        }
    }

If we try to create the following derived class:

    public class SomeEntityProxy : SomeEntity
    {
    }

We get the following compiler error:

Error 1 'ConsoleApplication1.SomeEntity.SomeEntity()' is inaccessible due to its protection level

It's a silly example, but it does show why entity types need at least a public or a protected default constructor and why a private one isn't sufficient.