Gennadiy Donchyts Just another WordPress weblog

3Feb/100

Is it good or bad practice to use events in Domain Classes?

Why to use events in entities?

.NET provides a native implementation of observer / subscriber pattern by means of events. I tried to use them not only in the UI classes but also to manage changes in the entities (see info about DDD for a definition of an entity). A lot of Entities in our application are in most cases bound to one or many controls. Entities are composed with other entities, they get changed, all these changes need to be monitored so that corresponding views will be updated or any other actions will be invoked.

Events in .NET is something to be used very carefully. Otherwise you'll end up with too many events :) . Finally we ended up with the two types of the events which are used in the entities and can be considered as Domain Events:

1. NotifyPropertyChanged - fired when any property changes, e.g. when name of the branch is changed - tree node needs to be updated, if branch is selected - it's name in the property grid control needs to be updated, etc.

2. NotifyCollectionChanged - fired when any collection is changed, add/remove item

Definition of Domain Event comes from the following post of Martin Fowler: http://martinfowler.com/eaaDev/DomainEvent.html

Once domain model is fully covered by events,  implementation of Undo / Redo functionality becomes trivial task (Memento pattern + these 2 types of events).

After a few tries we ended up with the following solution:

  • All objects implement INotifyPropertyChanged for all entities
  • All collections used in the properties implement INotifyCollectionChange, using interface IEventedList<T>: IList<T>, INotifyCollectionChanged
  • When events are fired in the child objects - they are bubbled to the higher level object

Of course implementing it by hand in every domain class is a violation of the DRY principle, so PostSharp were used to implement such behavior automatically by adding a few attributes on top of the entity class.

Example

Let's look on a very simple example, a blog containing blog posts and comments.

Without events it may look like this:

When events are used - there is simply no need for controller, everything can be bound directly to the view controls:

In this case view (or a very simple controller) subscribes to the changes in the domain model and then refreshes what needs to be refreshed.

Of course in reality there are some more issues, like:

  • Clients need to subscribe only to the events they need to use (filter)
  • Memory leak issues, solution: use weak events where possible http://diditwith.net/2007/03/23/SolvingTheProblemWithEventsWeakEventHandlers.aspx
  • Sometimes events need to be grouped or filtered (10000 items added to collection will generate 10000 events and therefore 10000 calls, if there are no subscribers - overhead is not that big, ~20% compare to the plain calls)

But in any case if events are used in as shown here - much less source code need to be produced plus data model always remain in sync with all views.

How events are fired and handled when blog title changes:

How events are fired and routed when new post is added:

Filed under: Uncategorized No Comments