Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,026 | Comments: 44,844

filter by tags archive

Concepts & Features in NH Prof: Filtering

time to read 3 min | 526 words

A while ago I mentioned the idea of Concepts and Features, I expounded it a bit more in the Feature by Feature post. Concepts and Features is the logical result of applying the Open Closed and Single Responsibility Principles. It boils down to a single requirement:

A feature creation may not involve any design activity.

Please read the original post for details about how this is actually handled. In this case, I wanted to show you how this works in practice with NH Prof. Filtering in NH Prof is a new concept, which allows you to limit what you are seeing in the UI based on some criteria.

The ground work for this feature include the UI for showing the filters, changing the UI to support the actual idea of filtering, and other related stuff. I can already see that we would want to be able to serialize the filters to save them between sessions, but that is part of what the concept is. It is the overall idea.

But once we have the concept outlined, thinking about features related to it is very easy. Let us see how we can build a new filter for NH Prof, one that filter out all the cached statements.

I intentionally choose this filter, because it doesn’t really have any options you need a UI for. Which make my task easier, but here is the UI, FilterByNotCachedView.xaml

		<TextBlock>Uncached statements</TextBlock>

And the filter implementation:

[DisplayName("Not Cached")]
public class FilterByNotCached: StatementFilterBase
	public override bool IsValid
		get { return true; }

	public override Func<IFilterableStatementSnapshot, bool> Process
			return snapshot => snapshot.IsCached == false;

Not hard to figure out what this is doing, I think.

This is all the code required, and NH Prof knows that it is going to pick it up from the appropriate places, and make use of it. This is why after adding these two files, I can now run NH Prof and I get the following:


I don’t think that I can emphasis enough how important this is to enable creating consistent and easy to handle solutions. Moreover, since most requests tend to be for features, rather than concepts, it is extremely easy to put up a new feature.

The end result is that I have a smart infrastructure layer, where I am actually implementing the concepts, and on top of it I am building the actual features. Just to give you an idea, NH Prof currently have just 6 concepts, and everything else is built on top of it.



When I see the code base I inherited to maintain and this blog entry, it looks like magic :(


Nice post again.

Could you explain why you have defined display name as an attribute and not as a read-only property?

Kyle Szklenski

Just a quick clarification: When you say, "May not involve", do you mean CANNOT, or should not? I'm assuming the former because it's you posting, but the latter seems more likely, just given systems I've seen. :)

Mike Minutillo

@Kyle - I would assume that Should Not would quickly devolve into usually does which becomes always does. Then the lines between Concepts & Features blur and your app becomes a big ball again making it difficult to add new features to your app.

@Ayende - I like this approach a lot. Would you consider this a valid approach for simple CRUD apps or is this overkill? I've done something like that before where you'd call a concept one of the standard actions (create, list, edit/update, delete, view) and each feature is essentially a new screen with UI and a presenter that dictates where the data comes from/goes.

Ayende Rahien


I would say that CRUD is a concept and a CRUD screen is a feature in this concept

Ayende Rahien


I am leaning toward must not.

Christopher Bennage

@Michael We use an attribute for the display name because we don't instantiate the filters in order to list them in the UI. The list of available filters is just a list of types, and the only addition metadata we needed was the display name.

Comment preview

Comments have been closed on this topic.


No future posts left, oh my!


  1. Technical observations from my wife (3):
    13 Nov 2015 - Production issues
  2. Production postmortem (13):
    13 Nov 2015 - The case of the “it is slow on that machine (only)”
  3. Speaking (5):
    09 Nov 2015 - Community talk in Kiev, Ukraine–What does it take to be a good developer
  4. Find the bug (5):
    11 Sep 2015 - The concurrent memory buster
  5. Buffer allocation strategies (3):
    09 Sep 2015 - Bad usage patterns
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats