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: 18 | Comments: 66

filter by tags archive

Fighting the architecture astronaut

time to read 4 min | 665 words

It is surprising how many other things I have to deal with in order to get a product up and running. Right now I am working on the web site for NH Prof, and I found myself tackling a problem in an interesting way.

The problem itself is pretty simple. I need to show a user guide, so people can lookup help topics, view alerts, etc.

My first instinct was to create a HelpTopics table and do a simple data driven help site. Literally just showing a list of the topics and allowing to view them. I got that working, and was busy creating my second help topic when I found out that I had to have some way of referencing another help topic.

Obviously I could just use a link, but that would tie one content of the help topics to the id of another, in a completely non obvious manner. Not to mention that when I deploy, it may very well have a different id.

At the time I was also fighting having to do updates to the content of the site using UPDATE statements (if the content is in the DB, then I need to update it somehow, and I figured that giving UI for that is too much of a hassle). I started thinking about solutions, using the title of the page for a link, wiki style, when I figured out that I was out of breath because I was architecting a trivial FAQ system as if it was Wikipedia.

I decided to take a step back, and try to do it all over again. This time, using such useful tools as HTML and pages. Here is what the current user guide looks like:


<h1>NHibernte Profiler User Guide</h1>
	<li><%=Html.ActionLink<LearnController>(x => x.Topic("ProfileAppWithConfiguration"),
		 "Configuring the application to be profile without changing the application code")%></li>
	<li><%=Html.ActionLink<LearnController>(x => x.Alert("SelectNPlusOne"), 
		"Select N+1")%></li>
	<li><%=Html.ActionLink<LearnController>(x => x.Alert("TooManyDatabaseCalls"), 
		"Too many database calls per session")%></li>
	<li><%=Html.ActionLink<LearnController>(x => x.Alert("UnboundedResultSet"), 
		"Unbounded result set")%></li>
	<li><%=Html.ActionLink<LearnController>(x => x.Alert("ExcessiveNumberOfRows"), 
		"Excessive / Large number of rows returned")%></li>
	<li><%=Html.ActionLink<LearnController>(x => x.Alert("DoNotUseImplicitTransactions"),
		"Use of implicit transactions is discouraged")%></li>
	<li><%=Html.ActionLink<LearnController>(x => x.Alert("LargeNumberOfWrites"), 
		"Large number of individual writes")%></li>

And here is the implementation of Topic and Alert:

public ActionResult Topic(string name)
	return View("~/Views/Learn/Topics/" + name + ".aspx");

public ActionResult Alert(string name)
	return View("~/Views/Learn/Alerts/" + name + ".aspx");

Now, if I want to edit something, I can do it in a proper HTML editor, and managing links between items has turned into a very trivial issue, like it is supposed to be.


Will Shaver

Sounds like a great case of JFHCI. Someone smart came up with that acronym a while back.

John Teague

If you don't want to create actions for each static page, you could route them all to one action with the name of the view as a parameter.

Something like this (from memory, so expect typos):


MapRoute("static_conent", "Learn/{vew}", new {controller = "Learn", action = "DisplayStatic"});

public ActionResult DisplayStatic(string view){

return View(view);





Ya man. KISS always wins.


Why not just use a wiki? Perhaps you will even trust your best end users to add comments and clarifications?

Comment preview

Comments have been closed on this topic.


  1. RavenDB 3.0 New Stable Release - 5 hours from now
  2. Production postmortem: The case of the lying configuration file - about one day from now
  3. Production postmortem: The industry at large - 2 days from now
  4. The insidious cost of allocations - 3 days from now
  5. Buffer allocation strategies: A possible solution - 6 days from now

And 4 more posts are pending...

There are posts all the way to Sep 11, 2015


  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    31 Aug 2015 - The case of the memory eater and high load
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats