Overridable Option

This is a tricky one to explain. The idea is that an option can take its value from multiple sources, but only one final value will be used, according to some priorities.
Think of it as a bucket where you put stuff from different sources. However the stuff somehow sorts itself, and you always grab only the stuff you need (yes, magic!)

Best of all here's a real life example: Your application supports multiple languages, but your users can choose their preferred language either by changing their preferences or by supplying an url query parameter. So you have a default language, the preferred language and the requested language. Your application needs to consider them in the following order
  • requested language is the most important
  • then the one from user prefs
  • then the default if nothing is set.

But those values can be set in any tier of the application at any time. You need the HttpRequest for one, the User Repository for another and the application settings for the default. You don't want to mix the Model layer with the View layer, the HttpRequest has nothing to do with your Db repository. So the solution is that each layer to provide the value when that layer is active, and not when the final value is needed.

In an application, it might be easier to set first the default value, then the requested one and then the one from user prefs. But if one value simply overrides the one before, the final value would be the one from user prefs, although the correct one is from url request. And that is the purpose of OverridableOption, to handle correctly this case.

Setup
public enum Sources
{
	Default = 1, //lowest priority
	UserPrefs = 2,  //medium priority
	Request = 3 //higher priority
}

//Init with default value, we have a dictionary with Source as keys and strings as values. The lambda expression is the sorting strategy. \
//In this case, enum is sorted as int, and the biggest number is also the most important
var t = new OverridableOption<Sources,String>(Sources.Default, "en", v => v[v.Keys.Max()]);

Example1
//We add the requested language  (the highest priority)
t.FromSource(Sources.Request, "fr");

//we add the userprefs language (medium priority)
t.FromSource(Sources.UserPrefs, "de");

//finalValue is "fr" as it is the requested language
var finalValue= = t.Value; 

Example2
//we add the userprefs language (medium priority)
t.FromSource(Sources.UserPrefs, "de");

//We add the requested language  (the highest priority)
t.FromSource(Sources.Request, "fr");

//finalValue is "fr" as it is the requested language
var finalValue= = t.Value; 

As you can see, the order in which you add the values isn't important to determine the final value.

Last edited Jan 21, 2011 at 12:00 PM by mike_sapiens, version 3

Comments

No comments yet.